1

我有三张桌子

  • 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 关系(表 Atable 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 的所有组合,第二部分选择 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。

于 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 回答