SQL笛卡尔加入问题
-
22-07-2019 - |
题
我有三个表
- A:A.pID主键,A.姓名权限(250)
- B:B.pID主键,B.的名字限(250)
- C:C.pID主键,C.名限(250)
有一个m n之间的关系A和B(表 lA_B
主钥匙 lA_B.pID
和 .pInstanceA
外键的表A和 .pInstanceB
外国的关键表格B)
有一个m n之间的关系A和C(table lA_C
主钥匙 lA_C.pID
和 .pInstanceA
外键的表A和 .pInstanceB
外国的关键表格C)
- 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 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我如何可以消除这个吗?
解决方案
你可能能够这样做与一个联盟:
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仅包括行匹配。行不匹配将会获得包括从加入在B。
注意到联盟的过滤器出重复行,就像不同。包括每一排,你可以使用的联盟。
其他提示
我认为该做的:
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
不隶属于 StackOverflow