Mysql
 sql >> Baza danych >  >> RDS >> Mysql

MySQL nie obsługuje klauzuli limit wewnątrz podselekcji, jak mogę to zrobić?

SELECT ... LIMIT nie jest obsługiwany w podzapytaniach, obawiam się, że czas uwolnić magię 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 w środku oblicza identyfikator artykułu o trzecim najniższym identyfikatorze dla każdej kategorii, próbując połączyć trzy kopie tej samej tabeli w rosnącej kolejności identyfikatorów. Jeśli w kategorii są mniej niż trzy artykuły, lewe sprzężenia zapewnią, że limit wynosi NULL, więc zewnętrzne WHERE również musi wybrać ten przypadek.

Jeśli twoje wymagania dotyczące „najlepszej 3” mogą w pewnym momencie zmienić się na „najlepsze n”, zaczyna to być nieporęczne. W takim przypadku możesz chcieć ponownie rozważyć pomysł przeszukiwania listy odrębnych kategorii, a następnie łączenia zapytań według kategorii.

ETA:Zamawianie na dwóch kolumnach:eek, nowe wymagania! :-)

Zależy, co masz na myśli:jeśli próbujesz tylko uporządkować wyniki końcowe, możesz to zrobić bez problemu. Ale jeśli musisz użyć tej kolejności, aby wybrać, które trzy artykuły mają zostać wybrane, sprawa jest o wiele trudniejsza.

Używamy samosprzężenia z „<”, aby odtworzyć efekt, jaki miałby „ORDER BY article_id”. Niestety, chociaż możesz zrobić „ORDER BY a, b”, nie możesz rób ‘(a, b)<(c, d)’... ani nie możesz zrobić ‘MIN(a, b)’. Poza tym w rzeczywistości zamawiasz według trzech kolumn, jest lepki, opublikowany i article_id, ponieważ musisz upewnić się, że każda wartość porządkowania jest unikalna, aby uniknąć zwracania co najmniej czterech wierszy.

Podczas gdy mogłeś stwórz swoją własną uporządkowaną wartość przez jakąś prymitywną kombinację liczb całkowitych lub ciągów kolumn:

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)

robi się to nierealnie brzydkie, a obliczenia stracą wszelkie szanse na użycie indeksów do zwiększenia wydajności zapytania. W tym momencie lepiej będzie po prostu wykonać oddzielne LIMIT zapytań na kategorię.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Data Java SQL jest przesunięta o 1 dzień

  2. Zaktualizuj wiersze po mysql select foreach

  3. mysql zapomina, kto jest zalogowany:odmowa polecenia użytkownikowi ''@'%'

  4. Wstawianie danych binarnych do MySQL (bez PreparedStatement's)

  5. Optymalizacja MySQL dla REGEXP