Sql 从同一列名中获取单元格值
我之前问过如何从可以看到的相同列值中获取行间的计数。提供的解决方案工作得非常好,但现在我需要额外的列来获取开始和结束之间的所有值 样本表 期望输出 以下是一个示例:Sql 从同一列名中获取单元格值,sql,sql-server,Sql,Sql Server,我之前问过如何从可以看到的相同列值中获取行间的计数。提供的解决方案工作得非常好,但现在我需要额外的列来获取开始和结束之间的所有值 样本表 期望输出 以下是一个示例: WITH sample_table(ID,Event,UserID)AS( SELECT 1,'START','000001' UNION ALL SELECT 2,'START','000002' UNION ALL SELECT 3,'END','000001' UNION ALL SELECT
WITH sample_table(ID,Event,UserID)AS(
SELECT 1,'START','000001' UNION ALL
SELECT 2,'START','000002' UNION ALL
SELECT 3,'END','000001' UNION ALL
SELECT 4,'PL','000002' UNION ALL
SELECT 5,'RC','000002' UNION ALL
SELECT 6,'END','000002'
)
SELECT t1.UserID,2+ISNULL(LEN(r.v)-LEN(REPLACE(r.v,',','')),0) AS [Row Count],STUFF(r.v,1,1,'') AS rowbetweenvalue
FROM sample_table AS t1
CROSS APPLY(SELECT top 1 ID AS ENDID FROM sample_table AS tt WHERE tt.UserID=t1.UserID AND tt.ID>t1.ID AND tt.Event='END' ORDER BY ID) c
CROSS APPLY(SELECT ','+st.Event FROM sample_table AS st WHERE st.UserID=t1.UserID AND st.ID>t1.ID AND st.ID<c.ENDID FOR XML PATH('')) AS r(v)
WHERE t1.Event='START'
根据Dudu Markovitz提供的解决方案,一种方法是: 创建并填充示例表请在以后的问题中保存此步骤
DECLARE @T AS TABLE
(
id int,
event varchar(5),
UserId char(6)
)
INSERT INTO @T VALUES
(1, 'START', '000001'),
(2, 'START', '000002'),
(3, 'END', '000001'),
(4, 'PL', '000002'),
(5, 'ZZ', '000002'),
(6, 'END', '000002')
将Dudu的答案封装到cte中
;WITH cte AS
(
select UserID
,min(ID) as from_ID
,max(ID) as to_ID
,count(*) as events
from (select UserID,ID,Event
, count(case when Event in ('START','END') then 1 end) over
(
partition by UserID
order by Id
rows unbounded preceding
)
- case when Event = 'END' then 1 else 0 end as group_seq
from @T
) t
group by UserID
,group_seq
having min(case when Event = 'START' then 1 end) = 1
)
查询:
SELECT UserId,
From_Id,
To_Id,
Events As eventCount,
STUFF(
(
SELECT ',' + event
FROM @T
WHERE UserId = cte.UserId
AND Id > from_ID
AND Id < to_ID
FOR XML PATH('')
)
, 1, 1, '') As events
FROM CTE
ORDER BY UserID ,from_id
如果两个标记之间有多条记录,您打算为rowbetweenvalue显示什么?如果我可以像这样显示PL、RC、ZZ,那有什么好呢。一般来说,我在两个标记之间只有一条记录,但在很多情况下,我可能会得到不止一条记录。
DECLARE @T AS TABLE
(
id int,
event varchar(5),
UserId char(6)
)
INSERT INTO @T VALUES
(1, 'START', '000001'),
(2, 'START', '000002'),
(3, 'END', '000001'),
(4, 'PL', '000002'),
(5, 'ZZ', '000002'),
(6, 'END', '000002')
;WITH cte AS
(
select UserID
,min(ID) as from_ID
,max(ID) as to_ID
,count(*) as events
from (select UserID,ID,Event
, count(case when Event in ('START','END') then 1 end) over
(
partition by UserID
order by Id
rows unbounded preceding
)
- case when Event = 'END' then 1 else 0 end as group_seq
from @T
) t
group by UserID
,group_seq
having min(case when Event = 'START' then 1 end) = 1
)
SELECT UserId,
From_Id,
To_Id,
Events As eventCount,
STUFF(
(
SELECT ',' + event
FROM @T
WHERE UserId = cte.UserId
AND Id > from_ID
AND Id < to_ID
FOR XML PATH('')
)
, 1, 1, '') As events
FROM CTE
ORDER BY UserID ,from_id
UserId From_Id To_Id eventCount events
000001 1 3 2 NULL
000002 2 6 4 PL,ZZ