sql >> Database >  >> RDS >> Mysql

Top N per groep met meerdere tafelsamenvoegingen

Ook al specificeert u LIMIT 100, voor dit type zoekopdracht moet een volledige scan en tabel worden opgebouwd, waarna elk record wordt geïnspecteerd en een rij wordt genummerd voordat uiteindelijk wordt gefilterd op de 100 die u wilt weergeven.

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;

De aanpak hier is

  1. Groepeer op om NumSales te krijgen
  2. Gebruik variabelen om de verkopen per leverancier/product te nummeren
  3. Filter de genummerde dataset zodat er maximaal 3 per leverancier mogelijk zijn
  4. Bestel de rest bij NumSales DESC en retourneer slechts 100


  1. tabel- en kolomnaam dynamisch doorgeven met behulp van bindvariabelen

  2. Kan geen databasetabel met de naam 'gebruiker' maken in PostgreSQL

  3. probleem bij het installeren van mysql2 gem met rails3 op mac

  4. MONTHNAME() Voorbeelden – MySQL