2017-06-28 3 views
1

重複するレコードを作成せずに3つのテーブルを結合する方法を理解できない。正しくジョインしてグループ化する方法

私は私の最初のテーブルプロファイルを使用するクエリ、および田部の楽器を持っている:

SELECT 
    [p].[shopper_id] 
, [pi].[instrument_id] 
FROM 
    [dbo].[profile] [p] 
INNER JOIN [dbo].[profile_instruments] [pi] 
ON [pi].[PID] = [p].[PID] 
WHERE 
    [p].[date_created] > DATEADD(yy, -2, GETDATE()) 
    AND [p].[shopper_id] = '53D5444535434747A935E207C9EDD96A' 
ORDER BY 
    [p].[shopper_id]; 

このクエリは私に結果を提供します:

shopper_id instrument_id 
53D5444535434747A935E207C9EDD96A 35 
53D5444535434747A935E207C9EDD96A 17 

私の2番目のクエリは、テーブルプロファイルと表スタイルを使用しています。

SELECT 
    [p].[shopper_id] 
, [ps].[style_id] 
FROM 
    [dbo].[profile] [p] 
INNER JOIN [dbo].[profile_styles] [ps] 
ON [ps].[PID] = [p].[PID] 
WHERE 
    [p].[date_created] > DATEADD(yy, -2, GETDATE()) 
    AND [p].[shopper_id] = '53D5444535434747A935E207C9EDD96A' 
ORDER BY 
    [p].[shopper_id]; 

結果は次のとおりです。

01私は3つのテーブルプロファイル、楽器やスタイルを組み合わせると
shopper_id style_id 
53D5444535434747A935E207C9EDD96A 845 
53D5444535434747A935E207C9EDD96A 291 

は:

SELECT 
    [p].[shopper_id] 
    , [pi].[instrument_id] 
    , [ps].[style_id] 
FROM 
    [dbo].[profile] [p] 
INNER JOIN [dbo].[profile_instruments] [pi] 
ON [pi].[PID] = [p].[PID] 
INNER JOIN [dbo].[profile_styles] [ps] 
ON [ps].[PID] = [p].[PID] 
WHERE 
    [p].[date_created] > DATEADD(yy, -2, GETDATE()) 
    AND [p].[shopper_id] = '53D5444535434747A935E207C9EDD96A' 
ORDER BY 
    [p].[shopper_id]; 

私は結果を得る:私はわからないですので、私はまだして、グループを使用していない

shopper_id instrument_id style_id 
53D5444535434747A935E207C9EDD96A 35 845 
53D5444535434747A935E207C9EDD96A 35 291 
53D5444535434747A935E207C9EDD96A 17 845 
53D5444535434747A935E207C9EDD96A 17 291 

どのように私が持っているコラムでそれを適用してください。私はまた、私が使用している結合のタイプのため、または私がグループを使用していないために重複があるかどうか不明です。いずれにしても

、私は私がどのように見えるの出力を持つために作るために必要なものを私のクエリへの変更を見つけ出すことができるようにいくつかの助けを賜りますようお願い申し上げ:

shopper_id instrument_id style_id 
53D5444535434747A935E207C9EDD96A 35 845 
53D5444535434747A935E207C9EDD96A 17 291 

ありがとうございましたあなたの助けのために事前に。

+0

instrument_ID 35がstyle_ID 845ではなく291であることをどのように知っていますか?この関係を定義する関連付けが不足しているだけです。それがなければ、あなたが見ている4つの結果が得られます。だから、最後の参加には、PSとPSが必要ですか? = PI。???どちらの楽器とどのスタイルの結びつきを示すか。重要でない場合は、各レコードに行番号を割り当てて行番号に結合することができますが、これは両方の表が買い物客あたりのレコード数が同じであることを前提としています。 – xQbert

+0

これらはお互いに独立しています。プロファイルとインストゥルメント、プロファイルとスタイルとの間には関係がありますが、インストゥルメントとスタイルの間には関係がありません。 –

+0

35が291の代わりに845にどうなるのか?繰り返しますが、この例では2レコードの予想結果がどのように得られているのか分かりません。実際に行数よりも重要でない場合は、数の概念が有効です。各テーブルのレコード数が同じであると仮定したり、買い物客1人あたりのレコード数が同じでない場合は、外部結合を使用する必要があります。 – xQbert

答えて

2

私たちは、各PIDのための各スタイルや楽器に行番号を割り当てます。次に、PIDで結合するだけでなく、p_IDに2つのインストゥルメントと2つのスタイルがある場合、2つのレコードしか取得できないRow_numberで結合します。

2つの楽器は存在しますが、1つのスタイルまたは2つのスタイルだけが存在し、1つの楽器のみが存在する状況を見たいかどうかは分かりません。

SELECT [p].[shopper_id] 
    , [pi].[instrument_id] 
    , [ps].[style_id] 
FROM [dbo].[profile] [p] 
INNER JOIN (SELECT A.*, row_number() over (partition by PID order by instrument_ID) RN 
      FROM [dbo].[profile_instruments] A) [pi] 
    ON [pi].[PID] = [p].[PID] 
FULL OUTER JOIN (SELECT A.*, Row_number() over (partition by PID order by style_ID) RN 
       FROM [dbo].[profile_styles] A) [ps] 
    ON [ps].[PID] = [p].[PID] 
AND [PI].[RN] = [PS].[RN] 
WHERE [p].[date_created] > DATEADD(yy, -2, GETDATE()) 
    AND [p].[shopper_id] = '53D5444535434747A935E207C9EDD96A' 
ORDER BY [p].[shopper_id]; 

我々はPI.RNの合体やPS.RNかを使用することができるかもしれ両方のあなたはスタイルや楽器が異なるカウントを持っている場合のいずれかのテーブルに単一の値に一致することであることをことを受け入れることを喜んでいる場合許容

例:

PID STYLE_ID  PID Instrument_ID 
1 A    1 Z 
1 B 

The above should return 
1 A Z 
1 B 

But maybe you want 
1 A Z 
1 B Z 

我々は AND coalesce([PI].[RN],1) = coalesce([PS].[RN],1)AND [PI].[RN] = [PS].[RN]を変更するが、テストが発生する必要がある場合、これが動作する可能性があります。あたかも一面にpidのすべてのレコードがないかのように、あなたはまだ1つのテーブルでnullを取得します。

+0

こんにちはxQbert、構文エラーがスローされます。メッセージ102、レベル15、状態1、行7 'row_number'の近くの構文が正しくありません。 メッセージ156、レベル15、状態1、行10 'over'キーワードの構文が正しくありません。 –

+0

2番目のサブクエリでrow_numberの後に()がありませんでした。 (thx SqlZim) – xQbert

+0

スタイルまたは割賦IDが挿入または変更された場合、関連付けが変更される可能性があることに注意してください。 – xQbert

0

次のようになり、自然が参加作ってみましょう:

...

たぶん
SELECT 
    [p].[shopper_id], 
    [pi].[instrument_id], 
    [ps].[style_id] 
FROM 
    [dbo].[profile] [p], 
    [dbo].[profile_instruments] [pi], 
    [dbo].[profile_styles] [ps] 
WHERE 
    [p].[date_created] > DATEADD(yy, -2, GETDATE()) 
    AND [p].[shopper_id] = '53D5444535434747A935E207C9EDD96A' 
    AND [pi].[PID] = [p].[PID] 
    AND [ps].[PID] = [p].[PID] 
ORDER BY 
    [p].[shopper_id]; 
+0

楽器の2つのレコード*プロファイルごとに2つのスタイルのレコードが4つのレコードを生成します。私はこれがどのようにその周りになるかは分かりません。 – xQbert

+0

[古いスタイルのJOINを使用した嫌な癖 - Aaron Bertrand](http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/08/bad-habits-to-kick-using-old-style -joins.aspx) – SqlZim

+0

私は 'natural join'が実際に' natural join'と 'using'という単語を使用したと思っています。結合したい両方のテーブルで同じ名前のフィールドを定義しました – xQbert

関連する問題