Search code examples
sqlpostgresqldistinctdistinct-valuesdistinct-on

Postgres select distinct of cartesian product


How to select from two columns such that each value is seen only once?

For example. From this table:

Column A                             Column B
-------------------------------------------------------------------------
02131d36-06cc-408e-9e40-1de65fbf37f4 7495fc05-e244-426c-bdae-a5ee121be510
11c32339-1b77-46e1-9215-0b1d4ec0b1d3 7495fc05-e244-426c-bdae-a5ee121be510
39cb3ebd-bb7f-4023-ab44-65a0f3e4d6d2 7b9fb1b0-61d4-4424-af83-33b1b7e77bc1
39cb3ebd-bb7f-4023-ab44-65a0f3e4d6d2 7495fc05-e244-426c-bdae-a5ee121be510
94e66d74-f0ce-472b-ad68-a98e267038b8 7495fc05-e244-426c-bdae-a5ee121be510
ab8130c7-e6a3-46cc-9ebc-0f8aca698169 7b9fb1b0-61d4-4424-af83-33b1b7e77bc1
ab8130c7-e6a3-46cc-9ebc-0f8aca698169 7495fc05-e244-426c-bdae-a5ee121be510
94e66d74-f0ce-472b-ad68-a98e267038b8 7b9fb1b0-61d4-4424-af83-33b1b7e77bc1
02131d36-06cc-408e-9e40-1de65fbf37f4 c597af82-58d5-4630-87e5-939898cc68ed
11c32339-1b77-46e1-9215-0b1d4ec0b1d3 c597af82-58d5-4630-87e5-939898cc68ed
39cb3ebd-bb7f-4023-ab44-65a0f3e4d6d2 c597af82-58d5-4630-87e5-939898cc68ed
ab8130c7-e6a3-46cc-9ebc-0f8aca698169 c597af82-58d5-4630-87e5-939898cc68ed
94e66d74-f0ce-472b-ad68-a98e267038b8 c597af82-58d5-4630-87e5-939898cc68ed

Pull out this (both A and B distinct):

02131d36-06cc-408e-9e40-1de65fbf37f4 7495fc05-e244-426c-bdae-a5ee121be510
ab8130c7-e6a3-46cc-9ebc-0f8aca698169 7b9fb1b0-61d4-4424-af83-33b1b7e77bc1
94e66d74-f0ce-472b-ad68-a98e267038b8 c597af82-58d5-4630-87e5-939898cc68ed

I know there's a few combinations possible, I want any one of them but not all of them.

The table is made from a subset of cartesian product of distinct values of B and distinct values of A.

I have been meddling with window functions and group by's and have not gotten it to work yet.


Solution

  • using window functions:

    t=# create table so182(a text,b text);
    CREATE TABLE
    Time: 23.926 ms
    t=# copy so182 from stdin delimiter ' ';
    t=# select distinct first_value(a) over (partition by b),b from so182;
                 first_value              |                  b
    --------------------------------------+--------------------------------------
     02131d36-06cc-408e-9e40-1de65fbf37f4 | 7495fc05-e244-426c-bdae-a5ee121be510
     11c32339-1b77-46e1-9215-0b1d4ec0b1d3 | c597af82-58d5-4630-87e5-939898cc68ed
     39cb3ebd-bb7f-4023-ab44-65a0f3e4d6d2 | 7b9fb1b0-61d4-4424-af83-33b1b7e77bc1
    (3 rows)
    

    distinct on:

    t=# select distinct on (b) b,a from so182;
                      b                   |                  a
    --------------------------------------+--------------------------------------
     7495fc05-e244-426c-bdae-a5ee121be510 | 02131d36-06cc-408e-9e40-1de65fbf37f4
     7b9fb1b0-61d4-4424-af83-33b1b7e77bc1 | 39cb3ebd-bb7f-4023-ab44-65a0f3e4d6d2
     c597af82-58d5-4630-87e5-939898cc68ed | 11c32339-1b77-46e1-9215-0b1d4ec0b1d3
    (3 rows)
    
    Time: 0.263 ms