2016-06-30 10 views
1

Ich möchte top 2 Artikel meist von jedem Kunden bestellt bekommen. Ich kann folgende Daten aus der VerkaufstabelleWie am häufigsten wiederholt Spalte A pro Spalte B

--------------------------- 
|OrderAccount| Item  | 
|ABC  | Shoes #1 | 
|ABC  | Shoes #2 | 
|ABC  | Shoes #2 | 
|ABC  | Shoes #1 | 
|ABC  | Shoes #4 | 
|RDD  | Shoes #1 | 
|RDD  | Shoes #2 | 
|RDD  | Shoes #1 | 
|RDD  | Shoes #6 | 
|RDD  | Shoes #1 | 
---------------------------- 

wie bekomme ich die Daten obwohl? dies nicht funktioniert:

SELECT so.Item, 
    so.OrderAccount 
    FROM (
     SELECT so.Item, 
     so.OrderAccount, 
     row_number() OVER(Partition BY so.Item ORDER BY so.OrderAccount desc) as repeated 
     FROM SalesOrders so 
    WHERE so.Item IS NOT NULL 
     ) AS so 
    WHERE so.repeated <= 2 
    ORDER BY so.OrderAccount 
+0

Was das aktuelle Ergebnis ist, und das gewünschte Ergebnis? – jarlh

+0

Welches DBMS? MS SQL Server? –

Antwort

2

Dies könnte funktionieren.Es gibt mehr als 2 Zeilen zurück, wenn Konten die gleiche Anzahl von Bestellungen haben.

SELECT b.OrderAccount, b.Item 
FROM(
    SELECT *, RANK() OVER(PARTITION BY a.OrderAccount ORDER BY a.count_item DESC) AS RowRank 
    FROM(
     SELECT so.OrderAccount, so.Item, count(item) count_item 
     FROM SalesOrders so 
     GROUP BY so.OrderAccount, so.Item 
    ) a 
) b 
WHERE b.RowRank <= 2 
+0

"Es wird mehr als 2 Zeilen zurückgeben, wenn Konten die gleiche Anzahl von Bestellungen haben." - das ist ein günstiger Nebeneffekt! –

+0

Nur machen es klar, da die OP angefordert Top 2 Zeilen – Sergio

+1

nett! @ Sergio! Danke, Mann! – Afflatus

-1

ich es geschafft, eine funktionierende Lösung zu bekommen, aber es nutzt wirklich schlechte Praktiken und schreckliche Leistung auf real-life-Datenbanken (OrderAccount auf Kunden- und Element zu Element umbenannt umbenannt) haben :

-- get the top-product per customer 
SELECT customer, item, MAX(cnt) 
FROM (
    -- get all customer-item-pairs with the associated count 
    SELECT customer, item, COUNT(item) AS cnt FROM tbl GROUP BY customer,item 
) GROUP BY customer 

UNION -- combine that with the second-top-product per customer 

-- get the top-product per customer, but stripped of the first part of the result (so the second-top-product) 
SELECT customer, item, MAX(cnt) 
FROM (
    -- get all customer-item-pairs with the associated count 
    SELECT customer, item, COUNT(item) AS cnt FROM tbl GROUP BY customer,item 
    EXCEPT --except for the customer-item-pairs which are already top-products 
    --this is the same as get the top-product per customer 
    SELECT customer, item, MAX(cnt) 
    FROM (
     SELECT customer, item, COUNT(item) AS cnt FROM tbl GROUP BY customer,item 
    ) GROUP BY customer 
) GROUP BY customer 
+0

Entschuldigung, aber wenn Sie offen zugeben müssen, dass Ihre Antwort "wirklich schlecht" und "schrecklich" ist, lohnt es sich wahrscheinlich nicht –

0

Mann, Sie haben gerade einen Fehler über die Partition und Reihenfolge von. Sie möchten Top 2 Artikel von jedem Kunden erhalten. Sie müssen also nach Kunden partitionieren, und Sie haben #num in Artikel, so dass Sie nach Artikel bestellen müssen.

über:

SELECT so.Item, 
so.OrderAccount 
FROM (
    SELECT so.Item, 
    so.OrderAccount, 
    row_number() OVER(Partition BY so.OrderAccount ORDER BY so.Item desc) as repeated 
    FROM SalesOrders so 
WHERE so.Item IS NOT NULL 
    ) AS so 
WHERE so.repeated <= 2 
ORDER BY so.OrderAccount 
+0

Wo werden in dieser Anfrage die Bestellungen gezählt, um zu bestimmen, welche Artikel am häufigsten pro Kunde bestellt werden? –

+0

Funktioniert das? Ich stimme mit Unterstrich_d überein, die Vorkommnisse werden nicht gezählt. – Sergio

Verwandte Themen