sql >> Database >  >> RDS >> Mysql

Hoe de nieuwste vier items per categorie SELECTEREN?

Dit is het grootste probleem per groep, en het is een veel voorkomende SQL-vraag.

Zo los ik het op met outer joins:

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;

Ik neem aan dat de primaire sleutel van het item tabel is item_id , en dat het een monotoon toenemende pseudosleutel is. Dat wil zeggen, een grotere waarde in item_id komt overeen met een nieuwere rij in item .

Zo werkt het:voor elk item zijn er een aantal andere items die nieuwer zijn. Er zijn bijvoorbeeld drie items nieuwer dan het vierde nieuwste item. Er zijn nul items nieuwer dan het allernieuwste item. Dus we willen elk item vergelijken (i1 ) naar de set items (i2 ) die nieuwer zijn en dezelfde categorie hebben als i1 . Als het aantal van die nieuwere items minder dan vier is, i1 is er een van die we opnemen. Voeg het anders niet toe.

Het mooie van deze oplossing is dat het werkt, ongeacht hoeveel categorieën je hebt, en blijft werken als je de categorieën verandert. Het werkt ook als het aantal items in sommige categorieën minder dan vier is.

Een andere oplossing die werkt, maar vertrouwt op de MySQL-functie voor gebruikersvariabelen:

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 introduceerde ondersteuning voor standaard SQL-vensterfuncties. Nu kunnen we dit soort problemen oplossen zoals andere RDBMS dat doen:

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. De uitvoer van het SQL Developer-script kapt de breedte van sys_refcursor af

  2. hoe vind je alle indexen en hun kolommen voor tabellen, views en synoniemen in oracle

  3. Waarom commit SQL*Plus bij afsluiten?

  4. Salesforce SOQL van Java