2011-09-16 9 views
-3

私は時間から解決策を探していますが、cat get it。ダブルクロスの結果を持たないSQL Self Join

マイテーブル:

ID   name   value1  value2 
1   Meyer   20   _ 
2   Schmitt  20   _ 
3   Berger  _   20 
4   Chief   _   20 

私のクエリ:

SELECT A.ID, A.name AS nameA, B.name AS nameB, A.value1 
FROM table AS A INNER JOIN table AS B 
ON A.value1 = B.value2 

結果:

ID  nameA  nameB  value1 
1  Meyer  Berger  20 
1  Meyer  Chief  20 
2  Schmitt Berger  20 
2  Schmitt Chief  20 

これは、次のようになります。

ID  nameA  nameB  value1 
1  Meyer  Berger  20 
2  Schmitt  Chief  20 

どうすればこの結果が得られますか?

は、私はまた、GROUP BY A.nameを試してみましたが、間違った結果が得られます。

ID  nameA  nameB  value1 
1  Meyer  Berger 20 
2  Schmitt Berger 20 
+0

、私をたくさん助けましたか?おそらく、データベースの正規化について読むべきでしょう。 – fluffy

+3

私はあなたがレコードをどのように関連づけているのか理解していません。 「value1」と「value2」の値がすべて20の場合、「Meyer」は「Berger」にのみ属し、「Schmitt」は「Chief」にのみ属しているとはどう思いますか? –

+0

この作業を行うには、他の基準が必要です。たとえば、クエリはMeyer Bergerを返しますが、Meyer Chiefは返しません。 – Phil

答えて

2

あなたはDBMSを指定していません。これは、SQL Serverでテストされます。

with C as 
(
    select *, 
     row_number() over(partition by value1 order by ID) as rn1, 
     row_number() over(partition by value2 order by ID) as rn2 
    from YourTable 
) 
select A.ID, 
     A.name as nameA, 
     B.name as nameB, 
     A.value1 
from C as A 
    inner join C as B 
    on A.value1 = B.value2 and 
     A.rn1 = B.rn2 

テスト可能サンプル:

declare @T table 
(
    ID int, 
    name varchar(10), 
    value1 int, 
    value2 int 
) 
insert into @T values 
(1,   'Meyer',   20,   null), 
(2,   'Schmitt',  20,   null), 
(3,   'Berger',  null,  20), 
(4,   'Chief',   null,  20) 

;with C as 
(
    select *, 
     row_number() over(partition by value1 order by ID) as rn1, 
     row_number() over(partition by value2 order by ID) as rn2 
    from @T 
) 
select A.ID, 
     A.name as nameA, 
     B.name as nameB, 
     A.value1 
from C as A 
    inner join C as B 
    on A.value1 = B.value2 and 
     A.rn1 = B.rn2 
+0

Hej!まずはありがとうございます。それは解決策のように見えますが、申し訳ありません、私はsqliteを使って作業しています!そこにも可能ですか?私はWITH Cを見たことがありません(...)あなたは私にそれを説明できますか? sqliteでも可能ですか? – airfrank

+0

@airfrank - 'with c as 'は共通のテーブル式です。それがsqliteで利用可能かどうかわかりません。そうでなければ、代わりに2つのサブクエリを使用できるはずです。また、ランキング関数row_number()が必要です。なぜなら、sqliteについて何も知らないので、それがあなたのためのオプションであるかどうかは分かりません。 –

+0

ありがとう! row_numberのあなたのヒントは私を正しい答えにしました! – airfrank

2

この基準A.value1 = B.value2とご入力テーブルを結合するによると、マイヤーはバーガーとチーフ、とシュミットの両方に関係していますバーガーとチーフの両方に関連しています。だから、容疑者はあなたが私たちに言っていないことが関連しているかどうかの基準/ビジネスルールに多くがある。 ちょうどvalue1とvalue2をいくつかのファンキーな外部キーとして使用しているようです。メイヤーがチーフに関係しないと思う理由、あるいはシュミットがバーガーに関連しない理由はどういうわけかはっきりしない。

ID   name   value1  value2 
1   Meyer   20   _ 
2   Schmitt  20   _ 
3   Berger  _   20 
4   Chief   _   20 

だから、それはそうのは、value1とvalue2のを修正してみましょう、あなたのクエリに問題はありませんが、あなたのデータ構造の問題、

ID   name   value1  value2 
1   Meyer   10   _ 
2   Schmitt  20   _ 
3   Berger  _   10 
4   Chief   _   20 

今、あなたは正しい結果が得られます。しかし、より伝統的なデザインは、次のようになります。

PersonId PersonName BossPersonId 
1   Meyer   3 
2   Schmitt  4 
3   Berger  _ 
4   Chief   _ 

このクエリでは:

Select A.Id, A.PersonName, B.PersonName as BossName 
FROM table AS A INNER JOIN table AS B 
ON A.BossPersonId= B.PersonId 
+0

Hej!まずはありがとう!私はペアリングを気にしない!私は、何も二度ペアができないようにしたい。上記のコメントで説明したとおり。何か案は? – airfrank

0

私は今、それを解決しました。

表:値によって

ID  name   value1   value2 
1  Meyer  20    _ 
2  Muster  10    _ 
3  Heinz  20    _ 
4  Karl   _    20 
5  Max   _    20 
6  Zack   _    10 

一時テーブルと順に分割して、それが

表A:

ID  name  value1  value2 
1  Muster  10   _ 
2  Meyer  20   _ 
3  Heinz  20   _ 

表B:次いで

ID  name  value1  value2 
1  Zack  _    10 
2  Karl  _    20 
3  Max   _    20 

とジョインA.ID = B.IDおよびA.value1 = B 。ROWNUMBERとvalue2の

ポストは正確にあなたがここでやろうとしている何THX よろしく

関連する問題