Postgres выбирает отдельные строки для каждой группы без повторения - PullRequest
0 голосов
/ 31 мая 2018

У меня есть запрос, который сгенерировал такие данные, как это.Для каждого родителя мне нужно выбрать ребенка, но не повторять ту же комбинацию или родителя или ребенка.На рисунке ниже черная граница показывает группы, а выделенные синим цветом строки - это строки, которые я хочу вернуть.

Data Table

У меня также есть случай, когдаЕсть 6 родителей и только 3 детей.В этом случае я хочу только 3 строки максимум, дочерний и родительский идентификаторы не могут повторяться.Я просто хочу, чтобы первые дети соответствовали родителям.

Ответы [ 2 ]

0 голосов
/ 02 июня 2018

Метод рок-н-ролла: просто выполните все задания и пропустите ошибки:


\i tmp.sql

 -- The data [in non-graphical form]
CREATE TABLE tableau(
        parent integer NOT NULL
        , child integer NOT NULL
        , PRIMARY KEY (parent,child)
        ) ;

INSERT INTO tableau(parent,child) VALUES
( 450759,450768) , ( 450759,450771) , ( 450759,450773)
, ( 450763,450768) , ( 450763,450771) , ( 450763,450773)
, ( 450765,450768) , ( 450765,450771) , ( 450765,450773)
        ;

-- Receptor table for the results:
CREATE TEMP TABLE assignment(
        parent integer NOT NULL UNIQUE
        , child integer NOT NULL UNIQUE
        );

-- Just do it!
INSERT INTO assignment(parent,child)
SELECT parent,child
FROM tableau
ON CONFLICT DO NOTHING --<< MAGIC!
  ;

SELECT * FROM tableau;
SELECT * FROM assignment;

Результаты:


CREATE SCHEMA
SET
CREATE TABLE
INSERT 0 9
CREATE TABLE
INSERT 0 3
 parent | child  
--------+--------
 450759 | 450768
 450759 | 450771
 450759 | 450773
 450763 | 450768
 450763 | 450771
 450763 | 450773
 450765 | 450768
 450765 | 450771
 450765 | 450773
(9 rows)

 parent | child  
--------+--------
 450759 | 450768
 450763 | 450771
 450765 | 450773
(3 rows)

Примечание: решение является жадным ;он может не найти оптимального решения для некоторых типов табличных данных.

0 голосов
/ 31 мая 2018

Так что я провел некоторое исследование и нашел варианты, которые были близки, но не помогли.Я наконец-то получил именно то, что хотел.

    WITH firstmatched AS (
    SELECT parent, 
           child, 
           ROW_NUMBER() OVER(PARTITION BY child 
                                 ORDER BY parent DESC) AS rowkey1,
           ROW_NUMBER() OVER(PARTITION BY parent 
                                 ORDER BY child DESC) AS rowkey2    
      FROM mytable)
    SELECT *
    FROM firstmatched where rowkey1 = rowkey2

Возьмите случай, когда есть 6 родителей и только дети, этот запрос без предложения where (где rowkey1 = rowkey2) выглядит так.

Matched Data

Затем с добавлением предложения where это сводится к этому.

Reduced Final Data

Надеюсь, это поможет кому-то с подобной проблемой.

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