Как сгруппировать результаты по компании? - PullRequest
2 голосов
/ 29 апреля 2019

У меня есть следующее 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 недействителен и т. Д.

1 Ответ

1 голос
/ 29 апреля 2019

Ваш пример выходных данных выглядит как массив 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;  

Чтобы получить три «самых последних»сотрудники, которых вы можете использовать:

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;

Онлайн Пример: https://rextester.com/RPSI96409

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...