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

MySQL understøtter ikke limit-klausulen i et undervalg, hvordan kan jeg gøre det?

VÆLG ... LIMIT understøttes desværre ikke i underforespørgsler, så det er på tide at bryde selv-deltagelsesmagien ud:

SELECT article.*
FROM article
JOIN (
    SELECT a0.category_id AS id, MIN(a2.article_id) AS lim
    FROM article AS a0
    LEFT JOIN article AS a1 ON a1.category_id=a0.category_id AND a1.article_id>a0.article_id
    LEFT JOIN article AS a2 ON a2.category_id=a1.category_id AND a2.article_id>a1.article_id
    GROUP BY id
) AS cat ON cat.id=article.category_id
WHERE article.article_id<=cat.lim OR cat.lim IS NULL
ORDER BY article_id;

Bitten i midten udregner ID'et for den tredje-laveste ID-artikel for hver kategori ved at prøve at samle tre kopier af den samme tabel i stigende ID-rækkefølge. Hvis der er færre end tre artikler for en kategori, vil de venstre joinforbindelser sikre, at grænsen er NULL, så den ydre WHERE skal også hente den sag.

Hvis dit "top 3" krav kan ændre sig til "top n" på et tidspunkt, begynder dette at blive uhåndterligt. I så fald vil du måske genoverveje ideen om først at forespørge på listen over forskellige kategorier og derefter samle forespørgslerne pr. kategori.

ETA:Bestilling på to kolonner:eek, nye krav! :-)

Det afhænger af, hvad du mener:Hvis du kun prøver at bestille de endelige resultater, kan du slå det til sidst, uden problemer. Men hvis du skal bruge denne rækkefølge til at vælge, hvilke tre artikler der skal vælges, er tingene meget sværere.

Vi bruger en selv-join med '<' for at reproducere den effekt 'ORDER BY article_id' ville have. Desværre, mens du kan gøre 'BESTILLING AF a, b', kan du ikke gør '(a, b)<(c, d)'... du kan heller ikke gøre 'MIN(a, b)'. Derudover ville du faktisk bestille efter tre kolonner, issticky, publiceret og article_id, fordi du skal sikre, at hver ordreværdi er unik, for at undgå at få fire eller flere rækker returneret.

Mens du kunne sammensæt din egen rækkefølgelige værdi ved hjælp af et råt heltal eller strengkombination af kolonner:

LEFT JOIN article AS a1
ON a1.category_id=a0.category_id
AND HEX(a1.issticky)+HEX(a1.published_at)+HEX(a1.article_id)>HEX(a0.issticky)+HEX(a0.published_at)+HEX(a0.article_id)

dette bliver umådeligt grimt, og beregningerne vil forpurre enhver chance for at bruge indeksene til at gøre forespørgslen effektiv. På hvilket tidspunkt er du bedre stillet ved blot at udføre de separate LIMITed-forespørgsler pr. kategori.



  1. Hibernate kunne ikke hente SequenceInformation fra databasen

  2. Oracle-låse og bordlåse:Sådan fungerer det

  3. Importerer MS ACCESS DB til mySql?

  4. Får den nøjagtige tidsforskel fra MYSQL datetime-feltet