如何按公司对结果进行分组?
How do I group the results by company?
我有以下 sql fiddle:
CREATE TABLE companies (pk serial PRIMARY KEY, name text, max int);
INSERT INTO companies(name, max)
VALUES
('Company A', 3),
('Company B', 8),
('Company C', -1);
CREATE TABLE employees (pk serial PRIMARY KEY, company integer REFERENCES companies (pk),
name text, joined timestamp);
INSERT INTO employees (company, name, joined)
VALUES
(2, 'Jane', '2015-09-23 14:46:57'),
(2, 'Jack', '2015-09-23 14:46:57'),
(3, 'Frank', '2015-09-23 14:51:07'),
(2, 'Bob', '2015-09-23 14:56:11'),
(1, 'Carl', '2015-09-23 16:12:05'),
(1, 'Jason', '2015-09-23 16:15:35'),
(3, 'Fred', '2015-09-23 16:28:35'),
(2, 'Bruce', '2015-09-23 16:35:51'),
(1, 'Brian', '2015-09-23 16:36:17'),
(1, 'Ryan', '2015-09-23 16:36:22'),
(1, 'Peter', '2015-09-23 16:37:04'),
(3, 'Ed', '2015-09-23 16:37:11'),
(2, 'Jenny', '2015-09-23 16:37:15'),
(2, 'Jessica', '2015-09-24 09:52:46'),
(3, 'Anita', '2015-09-24 10:01:19'),
(3, 'Melanie', '2015-09-24 10:05:27'),
(3, 'Kathryn', '2015-09-24 10:05:29'),
(2, 'Ashely', '2015-09-24 10:19:46'),
(1, 'Valerie', '2015-09-24 14:49:05'),
(2, 'Jimmy', '2015-09-24 15:42:45'),
(3, 'Johnny', '2015-09-24 17:38:06'),
(1, 'Mick', '2015-09-25 14:49:10');
SELECT * -- choose the columns you want here
FROM (SELECT e.*, c.max,
row_number() over (partition by company order by joined desc) as rank
FROM employees e JOIN
companies c
on e.company = c.pk
) e
WHERE rank <= max or max = -1
这给出:
pk company name joined max rank
22 1 Mick 2015-09-25T14:49:10Z 3 1
19 1 Valerie 2015-09-24T14:49:05Z 3 2
11 1 Peter 2015-09-23T16:37:04Z 3 3
20 2 Jimmy 2015-09-24T15:42:45Z 8 1
18 2 Ashely 2015-09-24T10:19:46Z 8 2
14 2 Jessica 2015-09-24T09:52:46Z 8 3
13 2 Jenny 2015-09-23T16:37:15Z 8 4
8 2 Bruce 2015-09-23T16:35:51Z 8 5
4 2 Bob 2015-09-23T14:56:11Z 8 6
1 2 Jane 2015-09-23T14:46:57Z 8 7
2 2 Jack 2015-09-23T14:46:57Z 8 8
21 3 Johnny 2015-09-24T17:38:06Z -1 1
17 3 Kathryn 2015-09-24T10:05:29Z -1 2
16 3 Melanie 2015-09-24T10:05:27Z -1 3
15 3 Anita 2015-09-24T10:01:19Z -1 4
12 3 Ed 2015-09-23T16:37:11Z -1 5
7 3 Fred 2015-09-23T16:28:35Z -1 6
3 3 Frank 2015-09-23T14:51:07Z -1 7
如何获取结果以便按公司分组?例如我想要 3 行(每个公司 1 行),然后是每个公司的一组员工。例如,公司 A 看起来像:
1 [{"name": "Mick", "joined": "2015-09-25T14:49:10Z", "rank": 1},{"name": "Valerie", "joined": "2015-09-24T14:49:05Z", "rank": 2},{"name": "Peter", "joined": "2015-09-23T16:37:04Z", "rank": 3}]
我一直在尝试各种 GROUP By 语句并使 运行 陷入各种错误,其中 sql 无效等。
您的示例输出看起来有点像 JSON 数组(但是,不是有效的 JSON 值),所以您可能正在寻找这样的东西:
select c.pk, jsonb_agg(to_jsonb(e))
from employees e
join companies c on e.company = c.pk
group by c.pk;
要获得三个 "most recent" 员工,您可以使用:
select c.pk, jsonb_agg(e3.emp)
from (
select company,
to_jsonb(e) as emp,
row_number() over (partition by company order by joined desc) as rn
from employees e
) e3
join companies c on e.company = c.pk
where e3.rn <= 3;
我有以下 sql fiddle:
CREATE TABLE companies (pk serial PRIMARY KEY, name text, max int);
INSERT INTO companies(name, max)
VALUES
('Company A', 3),
('Company B', 8),
('Company C', -1);
CREATE TABLE employees (pk serial PRIMARY KEY, company integer REFERENCES companies (pk),
name text, joined timestamp);
INSERT INTO employees (company, name, joined)
VALUES
(2, 'Jane', '2015-09-23 14:46:57'),
(2, 'Jack', '2015-09-23 14:46:57'),
(3, 'Frank', '2015-09-23 14:51:07'),
(2, 'Bob', '2015-09-23 14:56:11'),
(1, 'Carl', '2015-09-23 16:12:05'),
(1, 'Jason', '2015-09-23 16:15:35'),
(3, 'Fred', '2015-09-23 16:28:35'),
(2, 'Bruce', '2015-09-23 16:35:51'),
(1, 'Brian', '2015-09-23 16:36:17'),
(1, 'Ryan', '2015-09-23 16:36:22'),
(1, 'Peter', '2015-09-23 16:37:04'),
(3, 'Ed', '2015-09-23 16:37:11'),
(2, 'Jenny', '2015-09-23 16:37:15'),
(2, 'Jessica', '2015-09-24 09:52:46'),
(3, 'Anita', '2015-09-24 10:01:19'),
(3, 'Melanie', '2015-09-24 10:05:27'),
(3, 'Kathryn', '2015-09-24 10:05:29'),
(2, 'Ashely', '2015-09-24 10:19:46'),
(1, 'Valerie', '2015-09-24 14:49:05'),
(2, 'Jimmy', '2015-09-24 15:42:45'),
(3, 'Johnny', '2015-09-24 17:38:06'),
(1, 'Mick', '2015-09-25 14:49:10');
SELECT * -- choose the columns you want here
FROM (SELECT e.*, c.max,
row_number() over (partition by company order by joined desc) as rank
FROM employees e JOIN
companies c
on e.company = c.pk
) e
WHERE rank <= max or max = -1
这给出:
pk company name joined max rank
22 1 Mick 2015-09-25T14:49:10Z 3 1
19 1 Valerie 2015-09-24T14:49:05Z 3 2
11 1 Peter 2015-09-23T16:37:04Z 3 3
20 2 Jimmy 2015-09-24T15:42:45Z 8 1
18 2 Ashely 2015-09-24T10:19:46Z 8 2
14 2 Jessica 2015-09-24T09:52:46Z 8 3
13 2 Jenny 2015-09-23T16:37:15Z 8 4
8 2 Bruce 2015-09-23T16:35:51Z 8 5
4 2 Bob 2015-09-23T14:56:11Z 8 6
1 2 Jane 2015-09-23T14:46:57Z 8 7
2 2 Jack 2015-09-23T14:46:57Z 8 8
21 3 Johnny 2015-09-24T17:38:06Z -1 1
17 3 Kathryn 2015-09-24T10:05:29Z -1 2
16 3 Melanie 2015-09-24T10:05:27Z -1 3
15 3 Anita 2015-09-24T10:01:19Z -1 4
12 3 Ed 2015-09-23T16:37:11Z -1 5
7 3 Fred 2015-09-23T16:28:35Z -1 6
3 3 Frank 2015-09-23T14:51:07Z -1 7
如何获取结果以便按公司分组?例如我想要 3 行(每个公司 1 行),然后是每个公司的一组员工。例如,公司 A 看起来像:
1 [{"name": "Mick", "joined": "2015-09-25T14:49:10Z", "rank": 1},{"name": "Valerie", "joined": "2015-09-24T14:49:05Z", "rank": 2},{"name": "Peter", "joined": "2015-09-23T16:37:04Z", "rank": 3}]
我一直在尝试各种 GROUP By 语句并使 运行 陷入各种错误,其中 sql 无效等。
您的示例输出看起来有点像 JSON 数组(但是,不是有效的 JSON 值),所以您可能正在寻找这样的东西:
select c.pk, jsonb_agg(to_jsonb(e))
from employees e
join companies c on e.company = c.pk
group by c.pk;
要获得三个 "most recent" 员工,您可以使用:
select c.pk, jsonb_agg(e3.emp)
from (
select company,
to_jsonb(e) as emp,
row_number() over (partition by company order by joined desc) as rn
from employees e
) e3
join companies c on e.company = c.pk
where e3.rn <= 3;