sql >> Databáze >  >> RDS >> Mysql

MySQL nepodporuje limitní klauzuli uvnitř podvýběru, jak to mohu udělat?

SELECT ... LIMIT není v dílčích dotazech podporován, obávám se, takže je čas prolomit kouzlo self-join:

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;

Bit uprostřed vypracovává ID článku s třetím nejnižším ID pro každou kategorii tak, že se pokouší spojit tři kopie stejné tabulky ve vzestupném pořadí ID. Pokud je v kategorii méně než tři články, levá spojení zajistí, že limit bude NULL, takže vnější WHERE musí vyzvednout tento případ také.

Pokud se váš požadavek na „top 3“ může v určitém okamžiku změnit na „top n“, začíná to být nepraktické. V takovém případě možná budete chtít znovu zvážit myšlenku dotazu nejprve na seznam odlišných kategorií a poté sjednotit dotazy podle kategorií.

ETA:Objednávání na dvou sloupcích:eek, nové požadavky! :-)

Záleží na tom, co máte na mysli:pokud se snažíte objednat pouze konečné výsledky, můžete to bez problémů udeřit. Ale pokud potřebujete použít toto řazení k výběru, které tři články se mají vybrat, je to mnohem těžší.

Používáme vlastní spojení s „<“, abychom reprodukovali efekt, který by měl „ORDER BY article_id“. Bohužel, zatímco můžete provést „OBJEDNAT PODLE a, b“, nemůžete do ‚(a, b)<(c, d)‘... ani nemůžeš udělat ‚MIN(a, b)‘. Navíc byste ve skutečnosti seřadili podle tří sloupců, issticky, publikovaných a article_id, protože musíte zajistit, aby každá hodnota objednávky byla jedinečná, abyste se vyhnuli vrácení čtyř nebo více řádků.

Zatímco mohli vytvořte si vlastní uspořádanou hodnotu pomocí nějakého hrubého celého čísla nebo řetězcové kombinace sloupců:

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)

to začíná být neskutečně ošklivé a výpočty zmaří jakoukoli šanci na použití indexů k tomu, aby byl dotaz efektivní. V tomto okamžiku je lepší jednoduše provádět samostatné OMEZENÉ dotazy pro jednotlivé kategorie.



  1. Limit velikosti datového typu JSON v PostgreSQL

  2. Jak funguje funkce RPAD() v MySQL

  3. Jak LTRIM() funguje v MariaDB

  4. SELECT DISTINCT je na mém stole v PostgreSQL pomalejší, než se očekávalo