Frage

Ich habe drei Tabellen

  • A: A.pID Primärschlüssel, A.Name nvarchar (250)
  • B: B.pID Primärschlüssel, B.Name nvarchar (250)
  • C: C.pID Primärschlüssel, C.Name nvarchar (250)

Es ist ein m zu n Beziehung zwischen A und B (Tabelle lA_B mit Primärschlüssel lA_B.pID und .pInstanceA Fremdschlüssel für Tabelle A und .pInstanceB Fremdschlüssel für Tabelle B)

Es ist ein m zu n Beziehung zwischen A und C (table lA_C mit Primärschlüssel lA_C.pID und .pInstanceA Fremdschlüssel für Tabelle A und .pInstanceB Fremdschlüssel für Tabelle C)

  • A1 ist im Zusammenhang mit B1, B2 und C1
  • A2 ist in Verbindung mit B3 und C2, C3
  • A3 ist in Verbindung mit B4
  • A4 ist in Verbindung mit C4
  • A5 hat keine Beziehung

Hier ist meine 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)

Diese Abfrage:

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) 

Rückkehr

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

Und nun die Frage :-) wie die Abfrage

erhalten
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 

Das Problem ist, dass, wenn ich die beiden machen verbinden mit B und C das Ergebnis alle Kombinationen von B C. hat Wie kann ich diese beseitigen?

War es hilfreich?

Lösung

Das könnte Sie der Lage sein, das zu tun mit einer 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)

Der erste Teil wählt alle Kombinationen von A und B, den zweiten Teil aller Kombinationen von A und C liegt.

Wenn Sie möchten, um herauszufiltern Zeilen wie (A4, NULL, NULL), weil es bereits eine Reihe (A4, NULL, C4), versuchen Sie diese Abfrage:

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

auf B die Verbindung, das sagt Zeilen umfasst, die eine Übereinstimmung in B haben, oder für die es keine Übereinstimmung in C. Der Join auf C enthält nur die Zeilen, die Übereinstimmung in C. Zeilen, die nicht übereinstimmen würden entweder erhalten von der Join auf B enthalten.

Beachten Sie, dass UNION doppelte Zeilen herausfiltert, wie DISTINCT. Um jede Zeile gehören, können Sie UNION ALL verwenden.

Andere Tipps

Ich denke, das tut es:

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top