Как агрегировать значения из двух столбцов в нескольких записях в одну - PullRequest
0 голосов
/ 10 июля 2020

Я использую MS SQL Server.

У меня есть несколько таких записей:

id   |   firstname     | startpoint   | endpoint   |    lastname     
---------------------------------------------------------------------
1    |   james         |  A           |   B        |    bond         
2    |   james         |  B           |   C        |    bond         
3    |   james         |  X           |   Z        |    bond         

единственная разница между этими записями - это начальная и конечная точки

Я бы хотел увидеть что-то вроде этого:

firstname      | startAndEndPoint    | lastname
-------------------------------------------------
james          | A, B, C, X, Z       | bond

Я пробовал select concat(startpoint, ', ', endpoint) as startAndEndPoint from table where lastname = 'bond', но он все равно дает мне такой результат:

firstname     | startAndEndPoint    | lastname
james         | A, B                | bond
james         | B, C                | bond
james         | X, Z                | bond

Я считаю array_agg () функция может помочь мне в соответствии с этим сообщением , но похоже, что функция доступна на postgres, а не sql сервере.

1 Ответ

1 голос
/ 10 июля 2020

Вы можете развернуть и объединить:

select firstname, lastname, string_agg(pt, ', ') as points
from (select t.*, v.pt,
             row_number() over (partition by firstname, lastname, pt order by pt) as seqnum
      from t cross apply
           (values (t.startpoint), (t.endpoint)) as v(pt)
     ) t
where seqnum = 1
group by firstname, lastname;

К сожалению, string_agg() не поддерживает distinct. Однако это легко исправить, используя row_number().

Edit:

Если вы хотите идентифицировать каждый отдельный подключенный компонент, вы можете использовать рекурсивный CTE:

with cte as (
      select id, firstname, lastname,
             convert(varchar(max), concat(startpoint, ', ', endpoint)) as points,
             endpoint
      from t
      where not exists (select 1 from t t2 where t2.endpoint = t.startpoint)
      union all
      select cte.id, cte.firstname, cte.lastname,
             concat(cte.point, ', ', cte.endpoint), t.endpoint
      from cte join
           t
           on t.startpoint = cte.endpoint and t.id = cte.id
    )
select *
from cte;

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

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