1

私は3つのテーブルを持っています

  • A: A.pID 主キー、A.Name nvarchar(250)
  • B: B.pID 主キー、B.Name nvarchar(250)
  • C: C.pID 主キー、C.Name nvarchar(250)

AとBの間にam対nの関係があります(lA_B主キーlA_B.pID.pInstanceAテーブルAへの.pInstanceB外部キーとテーブルBへの外部キーを持つテーブル)

AとCの間にam対nの関係があります(テーブルAへのtable lA_C主キーlA_C.pIDと外部キー、およびテーブルCへの外部キーを使用).pInstanceA.pInstanceB

  • A1 は B1、B2、および C1 と関連しています
  • A2 は B3 および C2、C3 と関係があります
  • A3 は B4 と関連しています
  • A4 は C4 と関連しています
  • A5 関係なし

ここに私のSQLがあります:

CREATE TABLE [dbo].[A]( [pID] [bigint] NOT NULL, [Name] [nvarchar](250) NULL )
CREATE TABLE [dbo].[B]( [pID] [bigint] NOT NULL, [Name] [nvarchar](250) NULL )
CREATE TABLE [dbo].[C]( [pID] [bigint] NOT NULL, [Name] [nvarchar](250) NULL)
CREATE TABLE [dbo].[lA_B]( [pID] [bigint] NOT NULL, [pInstanceA] [bigint] NULL, [pInstanceB] [bigint] NULL )
CREATE TABLE [dbo].[lA_C]( [pID] [bigint] NOT NULL, [pInstanceA] [bigint] NULL, [pInstanceB] [bigint] NULL )

INSERT INTO [dbo].[A] ([pID] ,[Name]) VALUES (1,'A1')
INSERT INTO [dbo].[A] ([pID] ,[Name]) VALUES (2,'A2')
INSERT INTO [dbo].[A] ([pID] ,[Name]) VALUES (3,'A3')
INSERT INTO [dbo].[A] ([pID] ,[Name]) VALUES (4,'A4')
INSERT INTO [dbo].[A] ([pID] ,[Name]) VALUES (5,'A5')

INSERT INTO [dbo].[B] ([pID] ,[Name]) VALUES (1,'B1')
INSERT INTO [dbo].[B] ([pID] ,[Name]) VALUES (2,'B2')
INSERT INTO [dbo].[B] ([pID] ,[Name]) VALUES (3,'B3')
INSERT INTO [dbo].[B] ([pID] ,[Name]) VALUES (4,'B4')

INSERT INTO [dbo].[C] ([pID] ,[Name]) VALUES (1,'C1')
INSERT INTO [dbo].[C] ([pID] ,[Name]) VALUES (2,'C2')
INSERT INTO [dbo].[C] ([pID] ,[Name]) VALUES (3,'C3')
INSERT INTO [dbo].[C] ([pID] ,[Name]) VALUES (4,'C4')

INSERT INTO [dbo].[lA_B] ([pID],[pInstanceA],[pInstanceB])   VALUES   (1,1,1)
INSERT INTO [dbo].[lA_B] ([pID],[pInstanceA],[pInstanceB])   VALUES   (2,1,2)
INSERT INTO [dbo].[lA_B] ([pID],[pInstanceA],[pInstanceB])   VALUES   (3,2,3)
INSERT INTO [dbo].[lA_B] ([pID],[pInstanceA],[pInstanceB])   VALUES   (4,3,4)

INSERT INTO [dbo].[lA_C] ([pID],[pInstanceA],[pInstanceB])   VALUES   (1,1,1)
INSERT INTO [dbo].[lA_C] ([pID],[pInstanceA],[pInstanceB])   VALUES   (2,2,2)
INSERT INTO [dbo].[lA_C] ([pID],[pInstanceA],[pInstanceB])   VALUES   (3,2,3)
INSERT INTO [dbo].[lA_C] ([pID],[pInstanceA],[pInstanceB])   VALUES   (4,4,4)

このクエリ:

SELECT
  A.Name AS A, 
  B.Name AS B, 
  C.Name AS C
FROM
  A  
  left JOIN lA_B  ON (A.pID = lA_B.pInstanceA)
  left JOIN B     ON (B.pID = lA_B.pInstanceB)
  left JOIN lA_C  ON (A.pID = lA_C.pInstanceA)
  left JOIN C     ON (C.pID = lA_C.pInstanceB) 

戻り値

A1 B1 C1
A1 B2 C1
A2 B3 C2
A2 B3 C3
A3 B4 ヌル
A4 ヌル C4
A5ヌルヌル

そして今、質問:-)受信するクエリの方法

A1 B1ヌル
A1 B2 ヌル
A1ヌル C1
A2 B3 ヌル
A2 ヌル C2
A2 ヌル C3
A3 B4 ヌル
A4 ヌル C4
A5ヌルヌル

問題は、結合を B と C の両方で行うと、結果に B C のすべての組み合わせが含まれることです。どうすればこれを排除できますか?

4

2 に答える 2

4

UNION でそれを行うことができるかもしれません:

SELECT A.Name AS A, B.Name AS B, NULL AS C 
FROM A
left JOIN lA_B ON (A.pID=lA_B.pInstanceA) 
left JOIN B ON (lA_B.pInstanceB=B.pID) 
UNION
SELECT A.Name AS A, NULL AS B, C.Name AS C 
FROM A
left JOIN lA_C ON (A.pID=lA_C.pInstanceA) 
left JOIN C ON (lA_C.pInstanceB=C.pID)

最初の部分は A と B のすべての組み合わせを選択し、2 番目の部分は A と C のすべての組み合わせを選択します。

行 (A4,NULL,C4) が既に存在するため、(A4,NULL,NULL) のような行を除外する場合は、次のクエリを試してください。

SELECT A.Name AS A, B.Name AS B, NULL AS C 
FROM A
LEFT JOIN lA_B ON (A.pID=lA_B.pInstanceA) 
LEFT JOIN B ON (lA_B.pInstanceB=B.pID) 
WHERE b.name is not null 
    or not exists(select * from lA_C where A.pID=lA_C.pInstanceA) 
UNION
SELECT A.Name AS A, NULL AS B, C.Name AS C 
FROM A
LEFT JOIN lA_C ON (A.pID=lA_C.pInstanceA) 
LEFT JOIN C ON (lA_C.pInstanceB=C.pID)
WHERE c.name is not null 
ORDER BY A,B,C

B での結合の場合、これは、B で一致する行、または C で一致しない行を含めることを意味します。C での結合には、C で一致する行のみが含まれます。どちらにも一致しない行は、 B の結合。

UNION は、DISTINCT のように重複する行を除外することに注意してください。すべての行を含めるには、UNION ALL を使用できます。

于 2009-05-08T12:02:50.620 に答える
0

私はこれがそれを行うと思います:

select a,
       case when b='zzz' then null else b end as b,
       case when c='zzz' then null else c end as c
from (SELECT  A.Name AS A
             ,b.Name as b
             ,'zzz' as c
      FROM  A    
      JOIN lA_B  ON (A.pID = lA_B.pInstanceA)  
      JOIN B     ON (B.pID = lA_B.pInstanceB)  
      union
      select  a.Name
             ,'zzz'
            ,c.NAme
      from A
      left JOIN lA_C  ON (A.pID = lA_C.pInstanceA)  
      left JOIN C     ON (C.pID = lA_C.pInstanceB)) as a
于 2009-05-08T12:36:48.837 に答える