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

MYSQL - Подреждане по идентификатор в DESC ред, групиране по X

Не сте разбрали как GROUP BY работи в SQL, поради функция на MySQL. В стандартния SQL всяка неагрегирана колона в оператора SELECT ТРЯБВА да бъде в клаузата GROUP BY (има изключение за колони, чиито стойности са 100% зависими от колона, която вече е в клаузата GROUP BY, въпреки че няколко варианта на SQL поддържат това изключение) .

MySQL не налага това по подразбиране, но стойностите на кои редове се използват за тези колони не е дефинирано. Въпреки че може да получите това, което искате, може и да не го направите. И дори да го направите, има шанс това да се промени в бъдеще.

Подреждането обикновено е независимо от GROUP BY, въпреки че ако не посочите клауза ORDER, тогава резултатите ще бъдат подредени въз основа на това, което е било необходимо за извършване на ГРУПИРАНЕТО (т.е. ако това помага да се подредят редовете в един ред, за да се направи GROUP BY тогава MySQL няма да си направи труда да пренареди записите след това, освен ако изрично не му кажете да го направи с клауза ORDER BY).

Така че с текущите ви данни, групирането по ads_post_id стойността на id, която се връща, може да бъде 22, 23, 24, 104, 250, 253 или 767. Кое MySQL ще избере да използва не е дефинирано.

С текущата ви корекция на данните това е тривиално, тъй като можете просто да получите MAX id:-

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

MAX ще върне 1 ред за всяка ГРУПИРАНА стойност.

Нормалният проблем е, че хората искат друга колона за този ред. Например кажете, че всеки от редовете във вашите примерни данни също има IP адрес и искате този, който се равнява на най-високия идентификатор за 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     
---------------------------------------------------------------------------

В този случай не можете просто да използвате MAX. Например, ако сте опитали:-

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

Ще получите следните върнати данни

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

Ако опитате следното в повечето разновидности на SQL, ще получите грешка. В MySQL с настройките по подразбиране бихте получили резултат, но кой IP адрес се връща не е дефиниран (и всъщност произволен).

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

Решенията за това са или да получите максималния идентификатор за всеки ads_post_id в подзаявка и след това да го присъедините обратно към таблицата, за да получите останалите стойности:-

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

Алтернатива е (зло)използването на агрегатната функция GROUP_CONCAT. GROUP_CONCAT ще върне всички стойности, свързани заедно в 1 поле, всяко разделено с , (по подразбиране). Можете да добавите клауза ORDER BY, за да наложите реда, в който са свързани. Можете да използвате SUBSTRING_INDEX, за да върнете всичко до първата запетая.

Това може да бъде полезно за прости данни, но става проблематично с текстови данни или полета, които не повече от 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. Как да отрежа водещия и задния цитат от MySQL ред?

  2. mysql актуализира колона с int въз основа на реда

  3. MySQL Съхранени процедури, Pandas и Използвайте multi=True при изпълнение на множество оператори

  4. Как мога да използвам оптимално COALESCE() в клаузата WHERE?

  5. Заявка за подреждане по последните три знака на колона