2011-08-16 13 views
4

OK、私は次のような動作をしています。SQL JOINとUNIONを一緒に使用する

私は「取引ヘッダ」テーブルと「取引詳細」テーブルを持っています。特定の機能の場合、詳細テーブルは「備考」データを抽出するために少しの正規化を必要とします。各明細レコードには、TranRemark1、TranRemark2およびTranRemark3列で指定された最大3つの注釈を含めることができます。

私はそれがうまくいくと思ったが、間違った数のレコードを返します。

SELECT 
b.ClientName, 
a.TranID, 
a.TranRemark1, 
a.TranDateOfService, 
a.TranPayment 
FROM 
(select TranRemark1, TranID from TranDetail 
union all 
select TranRemark2, TranID from TranDetail 
union all 
select TranRemark3, TranID from TranDetail) AS a 
LEFT JOIN TranHeader AS b ON 
b.TranID = a.TranID 
WHERE a.TranRemark1 = @RemarkCode; 

私が得る結果セットがCLIENTNAMEませTranDetailからwhere句と一致するレコードの数と一致しTranHeaderレコードの数に基づいています。たとえば、クライアント "Acme Inc."ヘッダーテーブルに3つのレコードがあり、上記のクエリを「1234」(これはTranDetailの1つのレコードと一致する)の注釈コードに使用します。結果セットには正しいレコードが3回表示されます。

EDIT だから私はこのような結果セットを取得するために、上記の例から期待:

ClientName--TranID--TranRemark1--TranDateOfService--TranPayment 
Acme Inc ADC11 1234   8-16-2011   45.11  

私は何を得ることはこれです:

ClientName--TranID--TranRemark1--TranDateOfService--TranPayment 
Acme Inc ADC11 1234   8-16-2011   45.11  
Acme Inc ADC11 1234   8-16-2011   45.11 
Acme Inc ADC11 1234   8-16-2011   45.11 

があることを覚えておいてくださいTranHeaderのクライアントの複数のレコードにすることができます。

私は右と完全に結合しようとしましたが、すべて同じになります。

ここで問題が解決しませんか?

ありがとうございました。

+1

どのRDBMSを使用していますか?期待される結果がどのようなものかの例を教えてください。 – Vache

+0

なぜTranHeaderで左結合を使用していますか?あなたの問題はTrandHeaderのTrandetailにあるレコードと一致する複数のレコードですか? – HLGEM

+0

Vache - MSSQL 2008 - 結果セットに関する質問を更新します。 HLGEM、問題はTranDetailから重複を取得していることです。クライアントは複数のヘッダートランザクションを持つことができ、その数が何であれ、トランドラスタルレコードにはその倍数が掛けられます。 – nth

答えて

4

あなたが交換してみことができます:OUTER SQLのSELECT DISTINCTを行い、その後、

LEFT JOIN 
    (SELECT DISTINCT 
     TranId, ClientName 
    FROM TranHeader 
) AS b ON 
b.TranID = a.TranID 
WHERE a.TranRemark1 = @RemarkCode; 
+0

はい、DISTINCTを追加すると問題が解決されます。ありがとう。以下も動作します: (TranDetail 組合からTranRemark1、たTranIDを選択FROM すべて TranRemark2、たTranIDを選択DISTINCT b.ClientName、 a.TranID、 a.TranRemark1、 a.TranDateOfService、 a.TranPaymentを選択しますTranDetail 組合から全て は、AS TranRemark3 TranDetailから、たTranID)を選択 LEFTがON bとTranHeaderをJOIN b.TranID = a.TranID WHERE a.TranRemark1 = @RemarkCode。 – nth

4

どの程度

SELECT 
    b.ClientName, 
    a.TranID, 
    a.TranRemark1, 
    a.TranDateOfService, 
    a.TranPayment 
WHERE a.TranRemark1 = @RemarkID JOIN TranHeader b ON b.TranID = a.TranID 
UNION ALL 
SELECT 
    b.ClientName, 
    a.TranID 
    a.TranRemark2, 
    a.TranDateOfService, 
    a.TranPayment 
WHERE a.TranRemark2 = @RemarkID JOIN TranHeader b ON b.TranID = a.TranID 
UNION ALL 
SELECT 
    b.ClientName, 
    a.TranID, 
    a.TranRemark3, 
    a.TranDateOfService, 
    a.TranPayment 
WHERE a.TranRemark3 = @RemarkID JOIN TranHeader b ON b.TranID = a.TranID 

私は当初

SELECT 
b.ClientName, 
a.TranID, 
a.TranRemark1, 
a.TranDateOfService, 
a.TranPayment, 
a.TranRemark1, 
a.TranRemark2, 
a.TranRemark3 
FROM 
TranDetail a JOIN TranHeader As b ON 
b.TranID = a.TranID 
WHERE a.TranRemark1 = @RemarkCode 
    OR a.TranRemark2 = @RemarkCode 
    OR a.TranRemark3 = @RemarkCode; 

を提案していますが、おそらく各発言のための別の行をしたいと思いましたか?

+0

Nathan - 私はあなたの最初のオプションを試して、私の最初のクエリの詳細レコードとヘッダーレコードの数を掛けたのと同じ結果を得ました。 REの2番目のオプション、はい私は結果セットが "正規化"されることを望んだ、すなわち各発言ごとに別々の行を持っていました。 – nth

0

ALL UNIONを行う場合:

LEFT JOIN TranHeader AS b ON 
b.TranID = a.TranID 
WHERE a.TranRemark1 = @RemarkCode; 

をして。 UNIONを実行すると、重複が処理されます。

DISTINCTを持つUNION ALLは、私が信じているものの、パフォーマンスは向上します。

関連する問題