Mysql
 sql >> Base de données >  >> RDS >> Mysql

Top N par groupe avec plusieurs jointures de table

Même si vous spécifiez LIMIT 100, ce type de requête nécessitera une analyse complète et la création d'une table, puis chaque enregistrement inspecté et numéroté des lignes avant de finalement filtrer les 100 que vous souhaitez afficher.

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;

L'approche ici est

  1. Regrouper par pour obtenir NumSales
  2. Utilisez des variables pour numéroter les ventes par fournisseur/produit
  3. Filtrer l'ensemble de données numéroté pour autoriser un maximum de 3 par fournisseur
  4. Commandez le reste par NumSales DESC et renvoyez seulement 100