как получить этот sql запрос - PullRequest
0 голосов
/ 05 апреля 2020

всем привет У меня проблема с этим запросом, мне нужно получить строки, в которых идентификатор имеет одинаковые номера:

id2 |  num
----+------
28  | 6
28  | 104
28  | 106
50  | 6
50  | 104

ожидаемый результат:

id2 | num
----+-----
28  | 6
28  | 104
50  | 6
50  | 104

результат не 28 106, потому что нет 50 106.

case 2:

id2 | num
----+-----
29  | 1
30  | 1
31  | 1

ожидаемый результат:

id2 | num
----+-----
29  | 1
30  | 1
31  | 1

извлекает все, потому что все идентификаторы имеют число равно 1

эти числа являются случайными, при условии, что если существует более двух идентификаторов, они должны иметь одинаковые числа в столбце 2

Ответы [ 3 ]

1 голос
/ 05 апреля 2020

Один из способов сделать это - подсчитать вхождения каждого значения num и сравнить его с количеством значений DISTINCT id2. Если они одинаковы, то значение num встречается для каждого значения id2. Затем вы можете SELECT строк из таблицы, которые соответствуют этим num значениям:

SELECT *
FROM data
WHERE num IN (SELECT num
              FROM data
              GROUP BY num
              HAVING COUNT(*) = (SELECT COUNT(DISTINCT id2) FROM data))
ORDER BY id2, num

Вывод (для первого набора данных):

id2     num
28      6
28      104
50      6
50      104

Вывод (для второго набора данных):

id2     num
29      1
30      1
31      1

Демонстрация по SQLFiddle

0 голосов
/ 05 апреля 2020

По сути, вы хотите подсчитать количество различных значений id2 в данных и количество различных значений id2 для каждого num. Если только Postgres поддерживается count(distinct) в качестве оконной функции, вы можете сделать:

select id2, num
from (select t.*,
             count(distinct t.id2) over (partition by t.num) as cnt_id2_on_num, 
             count(distinct t.id2) over () as cnt_id2
      from t
     ) t
where cnt_id2_on_num = cnt_id2;

Существует простой обходной путь, который представляет собой сумму dense_rank() s:

select id2, num
from (select t.*,
             (dense_rank() over (partition by t.num order by t.id2) +
              dense_rank() over (partition by t.num order by t.id2 desc)
             ) as cnt_id2_on_num, 
             (dense_rank() over (order by t.id2) +
              dense_rank() over (order by t.id2 desc)
             ) as cnt_id2
      from mytable t
     ) d
where cnt_id2_on_num = cnt_id2;

Если вы знаете, что дубликатов нет, вы можете написать это как:

select id2, num
from (select t.*,
             count(*) (partition by t.num) as cnt_id2_on_num, 
             (dense_rank() over (order by t.id2) +
              dense_rank() over (order by t.id2 desc)
             ) as cnt_id2
      from mytable t
     ) d
where cnt_id2_on_num = cnt_id2;
0 голосов
/ 05 апреля 2020

Другим способом является использование предложения OVER для подсчета вхождений каждого значения в num и сравнения с количеством различных значений в id2, которые можно соединять в боковом направлении:

CREATE TABLE mytable(
   id2 VARCHAR(11) 
  ,num INTEGER 
);
INSERT INTO mytable(id2,num) VALUES ('28',6);
INSERT INTO mytable(id2,num) VALUES ('28',104);
INSERT INTO mytable(id2,num) VALUES ('28',106);
INSERT INTO mytable(id2,num) VALUES ('50',6);
INSERT INTO mytable(id2,num) VALUES ('50',104);


select id2, num
from (
    select
           id2, num
         , count(*) over(partition by num) c_num
         , ca.c_id2
    from mytable
    left join lateral (select count(distinct id2) c_id2 from mytable) ca on true
    ) d
where c_num = c_id2
;
id2 | num
:-- | --:
28  |   6
50  |   6
28  | 104
50  | 104
CREATE TABLE mytable(
   id2 VARCHAR(11) 
  ,num INTEGER 
);
INSERT INTO mytable(id2,num) VALUES ('29',1);
INSERT INTO mytable(id2,num) VALUES ('30',1);
INSERT INTO mytable(id2,num) VALUES ('31',1);
select id2, num
from (
    select
           id2, num
         , count(*) over(partition by num) c_num
         , ca.c_id2
    from mytable
    left join lateral (select count(distinct id2) c_id2 from mytable) ca on true
    ) d
where c_num = c_id2
;
id2 | num
:-- | --:
29  |   1
30  |   1
31  |   1

дБ <> скрипка здесь

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