簡體   English   中英

SQL - 按第 1 列分組,按第 2 列排序

[英]SQL - group by column 1, order by column 2

這是我的情況,我有兩個表分別名為peoplecontacts

id name
1  dev one
2  dev two
3  dev three
4  dev five
5  dev four
id  person_id code_name updated_at
1   1         base1     2019-12-18 00:00:01
2   3         base2     2019-12-18 00:00:02
3   2         home      2019-12-18 00:00:03
4   2         home2     2019-12-18 00:00:04
5   3         work      2019-12-18 00:00:05
6   4         work      2019-12-18 00:00:06
7   5         base      2019-12-18 00:00:07
8   4         base2     2019-12-18 00:00:08
9   2         base      2019-12-18 00:00:09
10  5         work      2019-12-18 00:00:10

我正在嘗試從聯系人中獲取結果,其中它按最近的 updated_at 排序並按 person_id 分組(注意:不完全是 sql“分組依據”),這看起來類似於以下結果。

id  person_id code_name updated_at
10  5         work      2019-12-18 00:00:10
7   5         base      2019-12-18 00:00:07
9   2         base      2019-12-18 00:00:09
4   2         home2     2019-12-18 00:00:04
3   2         home      2019-12-18 00:00:03
8   4         base2     2019-12-18 00:00:08
6   4         work      2019-12-18 00:00:06
5   3         work      2019-12-18 00:00:05
2   3         base2     2019-12-18 00:00:02
1   1         base1     2019-12-18 00:00:01

目前,我正在按person_id descupdated_at desc對聯系人表進行排序,結果與我預期的有點接近,但並不完全正確。

在執行ORDER BY person_id DESC, updated_at DESC https://monosnap.com/file/xN0cuZAu2x2df4Q5qNDksKq5P3sEjU contact with id => 1時查看結果應該位於結果集的頂部,因為它是最近更新的所有結果。

注意:PostgreSQL 是我在這種情況下的第一個用例,但如果有任何區別,也很高興知道 MySQL。

我在PostgreSQL 9.3嘗試了以下內容。

數據樣本:

create table contact
(
    id int,
    person_id int,
    code_name varchar(20),
    updated_at timestamp
);

INSERT INTO contact VALUES
(1,1,'base1','2019-12-18 00:00:01'),
(2,3,'base2','2019-12-18 00:00:02'),
(3,2,'home','2019-12-18 00:00:03'),
(4,2,'home2','2019-12-18 00:00:04'),
(5,3,'work','2019-12-18 00:00:05'),
(6,4,'work','2019-12-18 00:00:06'),
(7,5,'base','2019-12-18 00:00:07'),
(8,4,'base2','2019-12-18 00:00:08'),
(9,2,'base','2019-12-18 00:00:09'),
(10,5,'work','2019-12-18 00:00:10');

詢問:

DROP TABLE IF EXISTS TEMP_Stage_Table;

SELECT  string_agg(id::text,',' order by updated_at desc) id,
    person_id,
    string_agg(code_name,',' order by updated_at desc) code_name,
    string_agg(updated_at::text,',' order by updated_at desc) updated_at INTO TEMP_Stage_Table 
FROM contact
GROUP BY person_id
ORDER BY MAX(updated_at) DESC;

SELECT  regexp_split_to_table(t.id, E',') AS id,
    t.person_id, 
    regexp_split_to_table(t.code_name, E',') AS code_name,
    regexp_split_to_table(t.updated_at, E',') AS updated_at 
FROM TEMP_Stage_Table t;

輸出:

在此處輸入圖片說明

(MySQL/MariaDB 語法)

這將找到一個人的每個“行組”的“排序”,對嗎?

SELECT MAX(updated_at), person_id
    FROM tbl GROUP BY person_id ;

所以,讓我們這樣利用它:

SELECT y.*
    FROM (SELECT MAX(updated_at) AS latest, person_id
               FROM tbl GROUP BY person_id ) AS x
    JOIN tbl AS y  USING(person_id)
    ORDER BY x.latest DESC, y.updated_at DESC;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM