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

MYSQL — kolejność według identyfikatora w kolejności DESC, grupowanie według X

Źle zrozumiałeś, jak GROUP BY działa w SQL, ze względu na funkcję MySQL. W standardowym SQL każda kolumna niezagregowana w instrukcji SELECT MUSI znajdować się w klauzuli GROUP BY (istnieje wyjątek dla kolumn, których wartości są w 100% zależne od kolumny znajdującej się już w klauzuli GROUP BY, chociaż kilka odmian SQL obsługuje to wyjątek) .

MySQL nie wymusza tego domyślnie, ale które wartości wierszy są używane dla tych kolumn, nie są zdefiniowane. Chociaż możesz dostać ten, którego chcesz, możesz też nie. A nawet jeśli to zrobisz, jest szansa, że ​​zmieni się to w przyszłości.

Kolejność jest zwykle niezależna od funkcji GROUP BY, chociaż jeśli nie określisz klauzuli ORDER, wyniki zostaną uporządkowane na podstawie tego, co było wymagane do wykonania grupowania (tj. jeśli pomaga uporządkowanie wierszy w jednej kolejności, aby wykonać GROUP BY wtedy MySQL nie będzie zawracał sobie głowy zmienianiem kolejności rekordów później, chyba że wyraźnie polecisz to za pomocą klauzuli ORDER BY).

Tak więc przy bieżących danych, grupując według ads_post_id, zwracana wartość id może wynosić 22, 23, 24, 104, 250, 253 lub 767. Nie zdefiniowano, który MySQL wybierze do użycia.

Przy bieżących naprawach danych jest to trywialne, ponieważ możesz po prostu uzyskać identyfikator MAX:-

SELECT ads_post_id, MAX(id) 
FROM fb_ads 
GROUP BY ads_post_id 
LIMIT 6

MAX zwróci 1 wiersz dla każdej wartości ZGRUPOWANEJ.

Normalny problem polega na tym, że ludzie chcą innej kolumny w tym wierszu. Załóżmy na przykład, że każdy z wierszy w Twoich przykładowych danych również miał adres IP, a chciałeś mieć ten, który odpowiada najwyższemu identyfikatorowi dla ads_post_id:-

id   | ads_post_id         ip_address
---------------------------------------------------------------------------
22   | 983314845117571     192.168.0.0
23   | 983314845117571     192.168.0.5
24   | 983314845117571     192.168.0.7    
104  | 983314845117571     192.168.0.0
250  | 983314845117571     192.168.0.4
253  | 983314845117571     192.168.0.6
767  | 983314845117571     192.168.0.1     
---------------------------------------------------------------------------

W takim przypadku nie możesz po prostu użyć MAX. Na przykład, jeśli próbowałeś:-

SELECT ads_post_id, MAX(id), MAX(ip_address) 
FROM fb_ads 
GROUP BY ads_post_id 
LIMIT 6

Otrzymasz następujące dane zwrócone

id   | ads_post_id         ip_address
---------------------------------------------------------------------------
767  | 983314845117571     192.168.0.7     
---------------------------------------------------------------------------

Jeśli spróbujesz wykonać następujące czynności w większości odmian SQL, otrzymasz błąd. W MySQL z ustawieniami domyślnymi otrzymasz wynik, ale zwracany adres IP nie jest zdefiniowany (iw efekcie losowy).

SELECT ads_post_id, MAX(id), ip_address 
FROM fb_ads 
GROUP BY ads_post_id 
LIMIT 6

Rozwiązaniem tego problemu jest uzyskanie maksymalnego identyfikatora dla każdego ads_post_id w zapytaniu podrzędnym, a następnie dołączenie go z powrotem do tabeli w celu uzyskania pozostałych wartości:-

SELECT a.ads_post_id,
        a.id,
        a.ip_address
FROM fb_ads a
INNER JOIN
(
    SELECT ads_post_id, MAX(id) AS max_id 
    FROM fb_ads 
    GROUP BY ads_post_id 
) sub0
ON a.ads_post_id = sub0.ads_post_id
AND a.id = sub0.max_id

Alternatywą jest (nad)używanie funkcji agregującej GROUP_CONCAT. GROUP_CONCAT przywróci wszystkie wartości połączone razem w 1 polu, każde oddzielone znakiem , (domyślnie). Możesz dodać klauzulę ORDER BY, aby wymusić kolejność ich łączenia. Możesz użyć SUBSTRING_INDEX, aby zwrócić wszystko do pierwszego przecinka.

Może to być przydatne w przypadku prostych danych, ale staje się problematyczne w przypadku danych tekstowych lub pól, które mogą mieć wartość NULL.

SELECT a.ads_post_id,
        SUBSTRING_INDEX(GROUP_CONCAT(id ORDER BY id DESC), ',', 1),
        SUBSTRING_INDEX(GROUP_CONCAT(ip_address ORDER BY id DESC), ',', 1)
FROM fb_ads 
GROUP BY ads_post_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. Inicjator typu dla "System.Data.Entity.Migrations.DbMigrationsConfiguration"1" zgłosił wyjątek

  2. Pisanie do bazy danych MySQL za pomocą pand przy użyciu SQLAlchemy, to_sql

  3. Dlaczego musimy zamknąć bazę danych MySQL po poleceniu zapytania?

  4. Zapytanie MySQL Wybierz, SUMA, POŁĄCZENIE LEWE

  5. Wildfly i automatyczne ponowne połączenie z bazą danych