SQL: как выбрать два поля одной и той же ОДНОЙ строки в группе?

Я использую Postgres 9.6.*

У меня есть это:

street | first_name | last_name
1st    | james      | bond
1st    | mr         | q 
1st    | ms         | m
2nd    | man        | with_golden_gun

Я хотел бы получить список различных адресов и первый набор «first_name» и «last_name» для каждого.

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

street | first_name | last_name
1st    | james      | bond
2nd    | man        | with_golden_gun

Я группирую по street и пробую MIN(first_name) и MIN(last_name) -- однако -- используя MIN, есть случаи, когда для каждой группы уникальных улиц я могу получить, казалось бы, случайное смешение и сопоставление first_name и last_name, которые могут быть не в одном ряду. Очевидно, что MIN (минимум) здесь не подходит для агрегатора.

мой вопрос: как мне обеспечить, чтобы first_name и last_name находились в одной строке?


person JasonGenX    schedule 12.10.2017    source источник
comment
какие rdbms вы используете?   -  person Mureinik    schedule 12.10.2017
comment
я использую постгрес   -  person JasonGenX    schedule 12.10.2017
comment
Каков первый набор «first_name» и «last_name» для каждого?   -  person less    schedule 12.10.2017
comment
насколько я понимаю, ЛЮБОЙ набор, где строка идентична для обоих значений. Я просто не хочу смешивать и сочетать, как Джеймс + with_golden_gun как набор first_name и last_name   -  person JasonGenX    schedule 12.10.2017
comment
Я думаю, @less спрашивал об определении порядка - он в алфавитном порядке?   -  person Error_2646    schedule 12.10.2017


Ответы (4)


Вы можете использовать оконную функцию row_number для запроса одной строки для каждой группы:

SELECT street, first_name, last_name
FROM   (SELECT street, first_name, last_name,
               ROW_NUMBER() OVER (PARTITION BY street ORDER BY first_name) AS rn
        FROM   mytable) t
WHERE  rn = 1
person Mureinik    schedule 12.10.2017

Вам нужно предложение «DISTINCT ON», но для этого требуется сортировка, например. имя:

SELECT
 DISTINCT ON (street)
 street, first_name, last_name
FROM table
ORDER BY street, first_name
person OBi    schedule 12.10.2017

-- Я группирую это на основе min first_name и получаю фамилию на основе этого имени

Select street, first_name, 
(select last_name from person o where o.first_name = x.first_name) 
from (Select street, min(first_name) as first_name  
from person v group by street) as x;

-- Выход

street | first_name | last_name
-------------------------------------
1st    | james      | bond
2nd    | man        | with_golden_gun

-- Можно ли совмещать поля имени и фамилии

Select street, min(concat(first_name , ' ' , last_name)) as name
from person group by street

-- Выход

street | name 
----------------------------
1st    | james bond
2nd    | man with_golden_gun
person Anonymous 11    schedule 12.10.2017

Как описано в Как показать номера строк в запросе PostgreSQL? вы можете получить номер строки. Затем вы можете ЗАКАЗАТЬ или ГДЕ ваш оператор выбора по желанию.

person less    schedule 12.10.2017
comment
не было моим отрицательным голосом, но я предположил, что ваш ответ здесь лучше всего подходит в качестве комментария. Ссылка на другой ответ и фраза «иди, посмотри, есть мой ответ» — это вообще дурной тон. Ответы должны стоять сами по себе, ссылки на поддержку. - person Twelfth; 12.10.2017