Mysql
 sql >> база данни >  >> RDS >> Mysql

MySQL не поддържа клаузата за ограничение в подселекция, как мога да направя това?

SELECT ... LIMIT не се поддържа в подзаявки, страхувам се, така че е време да разбием магията за самостоятелно присъединяване:

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;

Битът в средата изработва идентификатора на статията с третия най-нисък идентификатор за всяка категория, като се опитва да обедини три копия на една и съща таблица във възходящ ред на идентификатора. Ако има по-малко от три статии за категория, лявото свързване ще гарантира, че ограничението е NULL, така че външният WHERE трябва да вземе и този случай.

Ако вашето изискване за „топ 3“ може да се промени на „топ n“ в даден момент, това започва да става тромаво. В този случай може да искате да преразгледате идеята първо да направите заявка към списъка с различни категории, след това да обедините заявките по категория.

ETA:Поръчка в две колони:eek, нови изисквания! :-)

Зависи какво имате предвид:ако се опитвате само да поръчате крайните резултати, можете да го блъснете до края, без проблем. Но ако трябва да използвате това подреждане, за да изберете кои три артикула да бъдат избрани, нещата са много по-трудни.

Ние използваме самостоятелно присъединяване с „<“, за да възпроизведем ефекта, който би имал „ORDER BY article_id“. За съжаление, докато можете да направите „ПОРЪЧАЙТЕ ОТ a, b“, вие не можете do ‘(a, b)<(c, d)’... нито можете да направите ‘MIN(a, b)’. Освен това всъщност ще поръчвате по три колони, issticky, public и article_id, защото трябва да се уверите, че всяка стойност на поръчката е уникална, за да избегнете връщането на четири или повече реда.

Докато вие можете съставете своя собствена стойност за поръчка чрез някаква груба комбинация от цяло число или низ от колони:

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)

това става неосъществимо грозно и изчисленията ще спрат всяка възможност за използване на индексите, за да направят заявката ефективна. В този момент е по-добре просто да правите отделни заявки с ограничена категория по категория.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да получите остатък с помощта на MOD() в PostgreSQL, MS SQL Server и MySQL

  2. Mysql няма да стартира след надграждане на Mac OS X Yosemite (Mac OS 10.10)

  3. Стабилно/повтарящо се произволно сортиране (MySQL, Rails)

  4. Как мога да променя няколко таблици наведнъж в mysql?

  5. Задаване на външен ключ bigInteger на bigIncrements в Laravel 5.4