Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 从同一列名中获取单元格值_Sql_Sql Server - Fatal编程技术网

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