SQL笛卡尔连接问题
我有三个表
- A:A.pID 主键,A.Name nvarchar(250)
- B:B.pID 主键,B.Name nvarchar(250)
- C:C.pID 主键,C.Name nvarchar(250)
有A 和 B 之间是 am to n 关系(表 lA_B 具有主键
lA_B.pID
和 .pInstanceA
表 A 和 的外键>.pInstanceB
表 B 的外键)
A 和 C 之间存在 am to n 关系(表 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 的所有组合。我怎样才能消除这个问题?
I have three tables
- A: A.pID primary key, A.Name nvarchar(250)
- B: B.pID primary key, B.Name nvarchar(250)
- C: C.pID primary key, C.Name nvarchar(250)
There is a m to n relation between A and B (table lA_B
with primary key lA_B.pID
and .pInstanceA
Foreign key to table A and .pInstanceB
Foreign key to table B)
There is a m to n relation between A and C (table lA_C
with primary key lA_C.pID
and .pInstanceA
Foreign key to table A and .pInstanceB
Foreign key to table C)
- A1 is in relation with B1, B2 and C1
- A2 is in relation with B3 and C2, C3
- A3 is in relation with B4
- A4 is in relation with C4
- A5 has no relation
Here is my 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)
this query:
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)
returns
A1 B1 C1 A1 B2 C1 A2 B3 C2 A2 B3 C3 A3 B4 NULL A4 NULL C4 A5 NULL NULL
And now the question :-)
how to query to receive
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
The problem is that when I make the join both with B and with C the result has all the combinations of B C. How can I eliminate this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您也许可以使用 UNION 来做到这一点:
第一部分选择 A 和 B 的所有组合,第二部分选择 A 和 C 的所有组合。
如果您希望过滤掉像 (A4,NULL,NULL) 这样的行,因为有已经是一行 (A4,NULL,C4),请尝试以下查询:
对于 B 上的联接,这表示包括在 B 中匹配的行,或者在 C 中没有匹配的行。C 上的联接仅包括行与 C 中匹配的行。两者都不匹配的行将从 B 上的联接中包含进来。
请注意,UNION 会过滤掉重复的行,如 DISTINCT。 要包含每一行,您可以使用 UNION ALL。
You might be able to do that with a UNION:
The first part selects all combinations of A and B, the second part all combinations of A and C.
If you wish to filter out rows like (A4,NULL,NULL) because there is already a row (A4,NULL,C4), try this query:
For the join on B, this says to include rows that have a match in B, or for which there is no match in C. The join on C includes only rows which match in C. Rows that do not match either would get included from the join on B.
Note that UNION filters out duplicate rows, like DISTINCT. To include every row, you can use UNION ALL.
我认为这样做可以:
I think this does it: