SQL-按列1分组,按列2排序

时间:2019-12-18 04:43:59

标签: mysql postgresql

这是我的情况,我有两个分别名为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

我正在尝试从联系人获取结果,该联系人的结果由person_id按最新的updated_at和groupd排序(注意:不完全是sql“ group by”),看上去与以下结果类似。

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 desc updated_at desc 排序联系人表,其结果与我的预期相近,但并不完全正确。

ORDER BY person_id DESC, updated_at DESC进行id => 1 https://monosnap.com/file/xN0cuZAu2x2df4Q5qNDksKq5P3sEjU接触时查看结果应该位于结果集的顶部,因为它是所有结果的最新更新。

注意:在这种情况下,PostgreSQL是我的第一个用例,但是很高兴知道MySQL是否存在任何区别。

2 个答案:

答案 0 :(得分:0)

我在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;

输出:

enter image description here

答案 1 :(得分:0)

(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;
相关问题