Postgres выбирает отличный от декартового произведения

Как выбрать один из двух столбцов, чтобы каждое значение отображалось только один раз?

Например. Из этой таблицы:

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

Вытащите это (и A и B различны):

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

Я знаю, что возможно несколько комбинаций, я хочу любую из них, но не все.

Таблица составлена ​​из подмножества декартовых произведений с различными значениями B и различными значениями A.

Я вмешивался в работу с оконными функциями и группировкой, но пока не работал.

2 ответа

Решение

Используя оконные функции:

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)

отличается от:

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

Извините, я не могу сейчас проверить, работает ли это, но как насчет:

  1. Создание 2 временных таблиц, таких как:

    CREATE TABLE #ColumnA(id int NOT NULL AUTO_INCREMENT, columna varchar(30))
    CREATE TABLE #ColumnB(id int NOT NULL AUTO_INCREMENT, columnb varchar(30))
    
  2. Заполняя их как:

     INSERT INTO ColumnA SELECT DISTINCT columna FROM OriginalTable
     INSERT INTO ColumnB SELECT DISTINCT columnb FROM OriginalTable
    
  3. Присоединение:

    SELECT a.columna, b.columnb FROM ColumnA a OUTER JOIN ColumnB b ON a.id = b.id
    

Это не красиво, но должно работать. В пункте 1 я написал имена таблиц с # - похоже, они создают временные таблицы. Также AUTO_INCREMENT может отличаться в разных dbms' (в postgres для этой колонки достаточно "id serial"). Я могу проверить это позже, если нет лучших ответов.

Другие вопросы по тегам