Postgres每组选择不同的行而不重复

时间:2018-05-31 12:36:44

标签: sql postgresql

我有一个生成匹配数据的查询。对于每个父母,我需要选择一个孩子,但不要重复相同的组合或父母或孩子。在下图中,黑色边框显示组,蓝色突出显示的行是我想要返回的行。

Data Table

我也有6个父母和3个孩子的情况。在这种情况下,我只想要最多3行,子ID和父ID不能重复。我只想让第一个匹配的孩子成为父母。

2 个答案:

答案 0 :(得分:0)

所以我进行了一些研究,发现了很接近但没有做到的选择。我终于得到了我想要的东西。

    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

希望这可以帮助有类似问题的人。

答案 1 :(得分:0)

Rock& Roll-method:只需进行所有分配并跳过错误:

\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)

注意:此解决方案 greedy ;它无法在某些类型的画面数据上找到最佳解决方案。