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

Jak WYBRAĆ najnowsze cztery pozycje w kategorii?

To jest największy problem w grupie i jest to bardzo częste pytanie dotyczące SQL.

Oto jak rozwiązuję to za pomocą złączeń zewnętrznych:

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;

Zakładam, że klucz podstawowy item tabela to item_id i że jest to monotonicznie rosnący pseudoklucz. Oznacza to większą wartość w item_id odpowiada nowszemu wierszowi w item .

Oto, jak to działa:dla każdego przedmiotu istnieje kilka innych, nowszych przedmiotów. Na przykład istnieją trzy elementy nowsze niż czwarty najnowszy element. Nie ma żadnych nowszych pozycji niż najnowsza pozycja. Dlatego chcemy porównać każdy element (i1 ) do zestawu elementów (i2 ), które są nowsze i należą do tej samej kategorii co i1 . Jeśli liczba tych nowszych pozycji jest mniejsza niż cztery, i1 jest jednym z tych, które uwzględniamy. W przeciwnym razie nie dołączaj go.

Piękno tego rozwiązania polega na tym, że działa ono niezależnie od liczby posiadanych kategorii i działa nadal, jeśli zmienisz kategorie. Działa to również wtedy, gdy liczba przedmiotów w niektórych kategoriach jest mniejsza niż cztery.

Inne rozwiązanie, które działa, ale opiera się na funkcji zmiennych użytkownika 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;

W MySQL 8.0.3 wprowadzono obsługę standardowych funkcji okien SQL. Teraz możemy rozwiązać ten problem w sposób, w jaki robią to inne 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. Przewodnik po projektowaniu bazy danych dla systemu zarządzania zapasami w MySQL

  2. Limit zmian dla rozmiaru wiersza Mysql jest zbyt duży

  3. W MySQL wstawiono nieprawidłową liczbę całkowitą (2147483647)?

  4. Błąd? #1146 — Tabela „xxx.xxxxx” nie istnieje

  5. Używanie indeksu, używanie tymczasowe, używanie sortowania plików - jak to naprawić?