坚持代码连接 + row_number SQL 代码

Stuck with code concatenation + row_number SQL code

这是我的数据的样子:

id  type    row_number
---------------------------
1a  a         1
1a  a         2
1a  b         3
1a  b         4
1a  c         5
1a  b         6
2a  b         1
2a  b         2
2a  c         3
2a  a         4
2a  c   

我想要新变量 new_type 如下所述,

id  new_type    
-------------
1a  a_b_c   
2a  b_c_a   

例如:ID = 1a,购买次数 = 1 然后 new_type = 类型,它会添加另一种类型,如 concat(购买次数与下一个类型无关)。

试过这个代码“

select id,
stuff((case when t.seqnum = '1' then '_' + type else '' end) +
              (case when t.seqnum = '2' then '_' + type else '' end) +
              (case when t.seqnum = '3' then '_' + type else '' end),
              1, 1, '') as new_type
from (select t.id, t.type , min(t.rowno) as min_tp, row_number() over (partition by t.id order by min(t.rowno)) as seqnum
      from try2 as t
      group by t.id, t.type 
     ) t
group by id;

但这给了我一个错误:

SQL Error [8120] [S0001]: Column 't.seqnum' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

如果你只有几种类型,你可以这样做:

select id,
       stuff( max(case when seqnum = 1 then '_' + type else '' end) +
              max(case when seqnum = 2 then '_' + type else '' end) +
              max(case when seqnum = 3 then '_' + type else '' end),
              1, 1, ''
            ) as new_type
from (select t.id, t.type, min(t.times_purchased) as min_tp,
             row_number() over (partition by t.id order by min(t.times_purchased)) as seqnum
      from t
      group by t.id, t.type
     ) t
group by id;

每种类型都需要一个单独的 case

请注意,这里很容易使用 string_agg(),但无法控制结果字符串的顺序。

这适用于一些假设;如果我的 假设 是错误的,那么由您来修正它们,因为我们仍在等待您的尝试,等等。

您使用的是不受支持的 SQL 服务器版本这一事实也不会让这变得那么容易,但无论如何,这个 似乎 可以工作:

WITH YourTable AS(
    SELECT *
    FROM (VALUES('1a','a',1),
                ('1a','a',2),
                ('1a','b',3),
                ('1a','b',4),
                ('1a','c',5),
                ('1a','b',6),
                ('2a','b',1),
                ('2a','b',2),
                ('2a','c',3),
                ('2a','a',4),
                ('2a','c',NULL))V(id, [type], [row_number]))
SELECT YT.id,
       STUFF((SELECT '_' + sq.[type]
              FROM (SELECT T.id,
                           T.[type],
                           T.[row_number],
                           ROW_NUMBER() OVER (PARTITION BY T.id, t.[type] ORDER BY t.[row_number]) AS RN
                    FROM YourTable T
                    WHERE T.id = YT.id
                      AND t.[row_number] IS NOT NULL) sq
              WHERE sq.RN = 1
              ORDER BY sq.[row_number]
              FOR XML PATH(''),TYPE).value('.','varchar(MAX)'),1,1,'') AS new_type
FROM YourTable YT
GROUP BY YT.id;

db<>fiddle

我更喜欢使用 string_agg,以免对要连接的字符串数量做出假设。

select id,
string_agg(type, "_") within group (order by seqnum asc) as new_type
from
(
select t.id, t.type, min(t.times_purchased) as min_tp,
 row_number() over (partition by t.id order by min(t. times_purchased)) as seqnum
from table1 t
group by t.id, t.type
) as t
group by id