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

Как да ИЗБЕРЕТЕ най-новите четири артикула на категория?

Това е най-големият проблем-n-на-група и е много често срещан SQL въпрос.

Ето как го разрешавам с външни съединения:

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;

Предполагам, че е първичният ключ на item таблицата е item_id , и че това е монотонно нарастващ псевдоключ. Тоест по-голяма стойност в item_id съответства на по-нов ред в item .

Ето как работи:за всеки артикул има известен брой други елементи, които са по-нови. Например, има три елемента, по-нови от четвъртия най-нов елемент. Има нула артикули, по-нови от най-новия артикул. Така че искаме да сравним всеки елемент (i1 ) към набора от елементи (i2 ), които са по-нови и имат същата категория като i1 . Ако броят на тези по-нови елементи е по-малък от четири, i1 е един от тези, които включваме. В противен случай не го включвайте.

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

Друго решение, което работи, но разчита на функцията за потребителски променливи на MySQL:

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 въведе поддръжка за SQL стандартни прозоречни функции. Сега можем да решим този вид проблем по начина, по който го правят другите RDBMS:

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Java:Вмъкнете няколко реда в MySQL с PreparedStatement

  2. Как да премахнете крайния празен интервал в MySQL

  3. Как да премахнете стойността по подразбиране на колоната в MySQL

  4. Научете как да импортирате данни от Excel в база данни на MySQL

  5. LINQ to Entities не разпознава метода 'System.String ToString()' и този метод не може да бъде преведен в израз на магазин