sql >> Database teknologi >  >> RDS >> Mysql

Hvordan VÆLGER man de nyeste fire varer pr. kategori?

Dette er det største problem pr. gruppe, og det er et meget almindeligt SQL-spørgsmål.

Sådan løser jeg det med udvendige sammenføjninger:

SELECT i1.*
FROM item i1
LEFT OUTER JOIN item i2
  ON (i1.category_id = i2.category_id AND i1.item_id < i2.item_id)
GROUP BY i1.item_id
HAVING COUNT(*) < 4
ORDER BY category_id, date_listed;

Jeg antager den primære nøgle til item tabellen er item_id , og at det er en monotont stigende pseudokey. Det vil sige en større værdi i item_id svarer til en nyere række i item .

Sådan fungerer det:For hver vare er der et antal andre varer, der er nyere. For eksempel er der tre varer nyere end den fjerde nyeste vare. Der er nul varer nyere end den allernyeste vare. Så vi vil sammenligne hvert element (i1 ) til sættet af elementer (i2 ), der er nyere og har samme kategori som i1 . Hvis antallet af disse nyere elementer er mindre end fire, i1 er en af ​​dem, vi medtager. Ellers skal du ikke inkludere det.

Det smukke ved denne løsning er, at den virker, uanset hvor mange kategorier du har, og fortsætter med at fungere, hvis du ændrer kategorierne. Det virker også, selvom antallet af varer i nogle kategorier er færre end fire.

En anden løsning, der virker, men er afhængig af MySQL-brugervariable-funktionen:

SELECT *
FROM (
    SELECT i.*, @r := IF(@g = category_id, @r+1, 1) AS rownum, @g := category_id
    FROM (@g:=null, @r:=0) AS _init
    CROSS JOIN item i
    ORDER BY i.category_id, i.date_listed
) AS t
WHERE t.rownum <= 3;

MySQL 8.0.3 introducerede understøttelse af SQL standard vinduesfunktioner. Nu kan vi løse denne slags problemer, som andre RDBMS gør:

WITH numbered_item AS (
  SELECT *, ROW_NUMBER() OVER (PARTITION BY category_id ORDER BY item_id) AS rownum
  FROM item
)
SELECT * FROM numbered_item WHERE rownum <= 4;


  1. Automatisk stigning i tabelkolonnen

  2. Typer i MySQL:BigInt(20) vs Int(20)

  3. Sådan sikkerhedskopieres en krypteret database med Percona Server til MySQL 8.0

  4. når jeg indsætter persisk tegn i oracle db ser jeg spørgsmålstegnet