我有三张桌子
A和B之间存在n关系(表lA_B
与主键lA_B.pID
和.pInstanceA
外键到表A和.pInstanceB
外键到表B )
A和C之间存在n关系(table lA_C
与主键lA_C.pID
和.pInstanceA
外键到表A和.pInstanceB
外键到表C)
这是我的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 NULL A4 NULL C4 A5 NULL NULL
现在的问题是:-) 如何查询接收
A1 B1 NULL A1 B2 NULL A1 NULL C1 A2 B3 NULL A2 NULL C2 A2 NULL C3 A3 B4 NULL A4 NULL C4 A5 NULL NULL
问题在于,当我使用B和C进行连接时,结果具有B C的所有组合。如何消除这种情况?
答案 0 :(得分: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的所有组合,第二部分选择A和C的所有组合。
如果您希望过滤掉(A4,NULL,NULL)等行,因为已经存在一行(A4,NULL,C4),请尝试以下查询:
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。
答案 1 :(得分: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