2017-02-01 16 views
-1

Ich habe eine Datenbank mit Tabellen mit Produkten und Verkäufern. Jedes Produkt wird von einem Verkäufer verkauft, daher gibt es einen FK - PK - Link zwischen Products.SalespersonId und Salespeople.Id. Nichts Ungewöhnliches.Vermeiden Sie UNION Abfrage

Wir können einen Sub-Verkäufer haben, die zu einem Verkäufer ‚gehört‘, so hat die Tabelle eine Nullable-ParentSalespersonId Spalte die „Schweinsohr“ FK'd zurück zu Salespeople.Id PK ist.

Auswahl der Produkte von ausgewählten Verkäufern verkauft sind trivial, aber auch Produkte verkauft durch den Sub-Verkaeufer der gewählt Verkäufer erfordern eine UNION Auswahl:

SELECT * 
    FROM Products 
INNER JOIN Salespeople ON Salespeople.Id = Products.SalespersonId 
WHERE Salespeople.Id = <some vale> -- products sold directly 

UNION 

SELECT * 
    FROM Products 
INNER JOIN Salespeople AS Sub ON Sub.Id = Products.SalespersonId 
INNER JOIN Salespeople AS Parent 
     ON Parent.Id = Sub.ParentSalespersonId 
WHERE Parent.Id = <some vale>-- products sold indirectly 

Abgesehen davon, dass stumpf hässlich, dass UNION einen Leistungseinbruch verursacht, da zwei Abfragen ausgeführt werden müssen und nicht nur eine.

ich viele Datenbanken im Laufe der Jahre erstellt haben, und geschrieben 100 von Abfragen, aber ich dieses nicht begreifen kann ...

Wie sollen die Tabellen neu strukturiert werden, um zur Erreichung der Beziehungen erforderlich , aber die Notwendigkeit für diese hässliche UNION und zweite SELECT entfernen?

Dank

+1

vor Vermeidung 'UNION' vermeiden SELECT *' – Jodrell

+0

die zweite Abfrage nur versuchen, fügen Sie einfach eine Bedingung für salesperson.id OR parent.id gleich gewünschten Wert –

Antwort

1

Sie tun können, nicht einfach:

SELECT * 
FROM Products 
INNER JOIN Salespeople AS Sub ON Sub.Id = Products.SalespersonId 
LEFT JOIN Salespeople AS Parent 
     ON Parent.Id = Sub.ParentSalespersonId 
WHERE Parent.Id = <some vale> 
    OR Salespeople.Id = <some vale> 

Wie Jodrell in den Kommentaren erwähnt, ist es ausdrücklich auch ratsam, zu Wählen Sie die benötigten Spalten statt *.

+0

Danke. Das hat geholfen – radders

1

Sie es eine Abfrage in nur tun können:

SELECT * 
FROM Products as P 
    INNER JOIN Salespeople Sub ON Sub.Id = P.SalespersonId 
    LEFT OUTER JOIN Salespeople AS Parent ON Parent.Id = Sub.ParentSalespersonId 
WHERE 
    Sub.Id = <some vale> -- products sold directly 
    or Parent.Id = <some vale>-- products sold indirectly 
+0

Dank. Das half – radders

0

erm,

SELECT 
      * -- don't use SELECT * 
    FROM 
      [dbo].[Products] P 
     LEFT JOIN 
      [dbo].[Salespeople] I 
       ON I.[Id] = P.[SalespersonId] 
     LEFT JOIN 
      [dbo].[Salespeople] S 
       ON S.[Id] = P.[SalespersonId] 
     LEFT JOIN 
      [dbo].[Salespeople] P 
       ON P.[Id] = S.[ParentSalespersonId] 
    WHERE 
      I.[Id] IS NOT NULL 
     OR 
      P.[Id] IS NOT NULL;