坚持代码连接 + 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;
我更喜欢使用 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
这是我的数据的样子:
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;
我更喜欢使用 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