Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Top N pro Gruppe mit mehreren Tabellenverknüpfungen

Auch wenn Sie LIMIT 100 angeben, erfordert diese Art von Abfrage einen vollständigen Scan und die Erstellung einer Tabelle, dann wird jeder Datensatz überprüft und die Zeile nummeriert, bevor schließlich nach den 100 gefiltert wird, die Sie anzeigen möchten.

select
    vendorid, productid, NumSales
from
(
    select
        vendorid, productid, NumSales,
        @r := IF(@g=vendorid,@r+1,1) RowNum,
        @g := vendorid
    from (select @g:=null) initvars
    CROSS JOIN 
    (
        SELECT COUNT(oi.price) AS NumSales, 
               p.productid, 
               p.vendorid
        FROM products p
        INNER JOIN vendors v ON (p.vendorid = v.vendorid)
        INNER JOIN orders_items oi ON (p.productid = oi.productid)
        INNER JOIN orders o ON (oi.orderid = o.orderid)
        WHERE (p.Approved = 1 AND p.Active = 1 AND p.Deleted = 0)
        AND (v.Approved = 1 AND v.Active = 1 AND v.Deleted = 0)
        AND o.`Status` = 'SETTLED'
        AND o.Deleted = 0
        GROUP BY p.vendorid, p.productid
        ORDER BY p.vendorid, NumSales DESC
    ) T
) U
WHERE RowNum <= 3
ORDER BY NumSales DESC
LIMIT 100;

Der Ansatz hier ist

  1. Gruppieren nach, um NumSales zu erhalten
  2. Verwenden Sie Variablen, um die Verkäufe pro Anbieter/Produkt zu nummerieren
  3. Filtern Sie den nummerierten Datensatz, um maximal 3 pro Anbieter zuzulassen
  4. Bestellen Sie den Rest bei NumSales DESC und geben Sie nur 100 zurück