Объединить данные двойных строк в качестве вывода - PullRequest
0 голосов
/ 03 августа 2020

У меня есть пример таблицы с идентификаторами и именами, я хотел бы получить новую таблицу с уникальными идентификаторами и объединенными именами одного столбца (сгруппированными по идентификатору). Мои данные выглядят так (SQL Server 2017 и 2019 - SSMS):

HouseId,    Names
1,  William
1,  James
1,  Mason
1,  Ella
1,  Jackson
1,  Evelyn
2,  Colton
2,  Robert
3,  Austin
3,  Cooper
3,  Parker
4,  Daisy
5,  Edward
5,  River

Моя цель - получить следующий результат с помощью qry:

HouseId,    Names
1,  William, James, Mason, Ella, Jackson and Evelyn
2,  Colton and Robert
3,  Austin, Cooper and Parker
4,  Daisy
5,  Edward and River

Есть ли у кого-нибудь совет / предложение, как сделать это легко, не усложняя его кодом SQL? Значение double для houseid составляет от 2 до 60.

Спасибо за помощь!

Ответы [ 2 ]

2 голосов
/ 03 августа 2020

Желание and делает это довольно сложным. Кажется, вы заботитесь об упорядочивании имен - сохраняя порядок из исходной таблицы. Чтобы справиться с этим, я предполагаю, что есть столбец упорядочивания:

select houseid,
       (case when count(*) = 1 then max(name)
             else concat(string_agg(case when id <> max_id then name end, ', ') within group (order by id),
                         ' and ',
                         max(case when id = max_id then name end)
                        )
        end) as names
from (select t.*, max(id) over (partition by houseid) as max_id
      from t
     ) t
group by houseid;

Если у вас нет такого идентификатора для сохранения порядка, вы можете вместо него использовать name. Результаты имеют желаемый формат, но без столбца упорядочения порядок не может быть сохранен.

Здесь - скрипт db <>.

2 голосов
/ 03 августа 2020

Поскольку вы не указали, какую СУБД вы используете, я перечислю наиболее часто используемые.

MySQL (я считаю 5 +)

SELECT HouseId, GROUP_CONCAT(Names SEPARATOR ', ') AS Names
FROM YourTable
GROUP BY HouseId;

Oracle ( 11g +)

SELECT HouseId, LISTAGG(Names, ', ') AS Names
FROM YourTable
GROUP BY HouseId;

Postgres (9 +)

SELECT HouseId, STRING_AGG(Names, ', ') AS Names
FROM YourTable
GROUP BY HouseId;

SQL Сервер (2017 +)

SELECT HouseId, STRING_AGG(Names, ', ') AS Names
FROM YourTable
GROUP BY HouseId;

Для более старых версий Oracle, MySQL, Postgres вы можете написать свою собственную функцию. Для сервера SQL вы можете использовать FOR XML PATH и STUFF, чтобы добиться чего-то подобного. Для Postgres, который поддерживает array_to_string, вы можете использовать его вместе с array_agg.

Обратите внимание, что это будет разделять значения только запятой и пробелом, если вы хотите, чтобы последнее было разделено к слову and становится сложнее.

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