2016-11-04 5 views
7

Ich habe eine Abfrage so etwas wieLEFT OUTER JOIN mit nur ersten Reihe

SELECT S.product_id, S.link, C.id AS category_id 
FROM Products P 
INNER JOIN SEO S ON S.product_id = P.id AND P.product_type = 1 
LEFT OUTER JOIN Categories C ON c.product_id = P.id 
WHERE P.active = 1 

ich funktioniert für mich in Ordnung, solange jedes Produkt nur einer Kategorie zugeordnet. Wenn ein Produkt jedoch mehreren Kategorien zugeordnet ist, gibt es alle möglichen Kombinationen zurück.

Kann ich nur die erste auswählen und wenn ein Produkt die Verbindung mit category_id = NULL

+6

'Der erste', nach welchen Kriterien? – Lamak

+0

Sie könnten eine MIN oder MAX und GROUP BY für category_id hinzufügen. Wenn das nicht gut genug ist, verschieben Sie Kategorien in eine Unterabfrage. – Stavr00

Antwort

4

Eine einfache Möglichkeit ist äußeree Anwendung zu verwenden, um einen korrelierten zu haben beizutreten, und macht, dass eine Top-1-Abfrage. Somit können Sie auf alle Spalten des betreffenden Kategoriedatensatzes zugreifen. Ich füge hier einen Kategorienamen als Beispiel ein:

select s.product_id, s.link, c.id as category_id, c.name as category_name 
from products p 
inner join seo s on s.product_id = p.id 
outer apply 
(
    select top 1 * 
    from categories cat 
    where cat.product_id = p.id 
    order by cat.id 
) c 
where p.active = 1 
and p.product_type = 1; 
+0

Mit Outer anwenden ist es auch möglich, nach jeder Spalte in der Kategorie Tabelle zu bestellen, die er wahrscheinlich benötigt. – Magnus

3

Sie können eine GROUP BY verwenden zurückgegeben werden sollten keine Kategorie haben nach wie vor das mit einer Aggregate Funktion entlang zu erreichen, die meisten wahrscheinlich MIN oder MAX.

Je nachdem, welche Kategorie-ID Sie in Ihrem Ergebnis bevorzugen, können Sie das Minimum auswählen.

SELECT S.product_id, S.link, MIN(C.id) AS category_id 
FROM Products P 
INNER JOIN SEO S ON S.product_id = P.id AND P.product_type = 1 
LEFT OUTER JOIN Categories C ON c.product_id = P.id 
WHERE P.active = 1 
GROUP BY S.product_id, S.link 

Oder das Maximum.

SELECT S.product_id, S.link, MAX(C.id) AS category_id 
FROM Products P 
INNER JOIN SEO S ON S.product_id = P.id AND P.product_type = 1 
LEFT OUTER JOIN Categories C ON c.product_id = P.id 
WHERE P.active = 1 
GROUP BY S.product_id, S.link 
1

Alternative Lösung mit Unterabfrage:

SELECT S.product_id, S.link, 
(
SELECT C.id FROM Categories C WHERE C.product_id = P.id AND 
ROW_NUMBER() OVER(ORDER BY /* your sort option goes here*/) = 1 
) AS category_id 
FROM Products P 
INNER JOIN SEO S ON S.product_id = P.id AND P.product_type = 1 
WHERE P.active = 1