【问题标题】:SQL Server : calculation on grouped resultsSQL Server:计算分组结果
【发布时间】:2016-07-26 10:49:40
【问题描述】:

在 SQL Server 2014 中,来自一组记录(例如在 TableA 中),其中包含日期列 [LogDate](已记录时)、状态列 [Status](例如 0 和 1)和 UserID [UserID]同一用户的记录可能很少,在不同日期具有相同的状态。

我想锻炼时间差(对于所有用户),在第一次记录为状态 = 0 之间,然后每个用户的第一次状态 = 1(这样我可以获得那个时间的总和)。我相信它可以做到,我只是不断进入死胡同。我会很感激任何想法,所以我可以继续前进......

数据示例:

UserId  LogDate     Status
--------------------------
1       01/01/2016  1     
1       02/01/2016  1     
1       07/01/2016  1     
1       10/01/2016  0     
1       11/01/2016  1 
1       12/01/2016  0 
2       01/01/2016  1     
2       02/01/2016  1     
2       07/01/2016  0     
2       10/01/2016  0     
2       11/01/2016  1 
2       12/01/2016  0  

我希望得到 UserID = 1 的 9 天和 UserID = 2 的 6 天的结果。获得这些的总和似乎很简单。

计算用户 ID 1 的天数:状态=1 的第一条记录是 2016 年 10 月 1 日,状态=0 的第一条记录是 2016 年 1 月 1 日。这些日期之间的天数差为 9。

谢谢

【问题讨论】:

  • 请编辑您的问题并提供示例数据和所需的结果。
  • 9 天怎么算?请显示。

标签: sql sql-server grouping


【解决方案1】:

这是获取每个状态的第一个日期的一种方法:

select userId,
       max(case when seqnum = 1 and status = 0 then logDate end) as logDate_0,
       max(case when seqnum = 1 and status = 1 then logDate end) as logDate_1
from (select t.*,
             row_number() over (partition by userId, status order by logDate) as seqnum
      from t
     ) t
group by userId;

【讨论】:

    【解决方案2】:

    试试这个

    DECLARE @Tbl TABLE (UserId INT, LogDate DATETIME, Status INT)
    
    INSERT INTO @Tbl
    select 1 ,      '2016.01.01', 1    union all 
    select 1 ,      '2016.01.02', 1    union all 
    select 1 ,      '2016.01.07', 1    union all 
    select 1 ,      '2016.01.10', 0    union all 
    select 1 ,      '2016.01.11', 1    union all
    select 1 ,      '2016.01.12', 0    union all
    select 2 ,      '2016.01.01', 1    union all 
    select 2 ,      '2016.01.02', 1    union all 
    select 2 ,      '2016.01.07', 0    union all 
    select 2 ,      '2016.01.10', 0    union all 
    select 2 ,      '2016.01.11', 1    union all
    select 2 ,      '2016.01.12', 0    
    
    
    SELECT
        M.UserId,
        DATEDIFF(dd, MIN(M.StartLogDate) ,MIN(M.EndLogDate)) AS DayOfLogDate
    FROM
    (
        SELECT 
            C.UserId,               
            CASE WHEN C.Status = 1 THEN  C.LogDate ELSE (SELECT NULL) END AS StartLogDate,          
            CASE WHEN C.Status = 0 THEN  C.LogDate ELSE (SELECT NULL) END AS EndLogDate         
        FROM 
            @Tbl C
    ) M
    GROUP BY
        M.UserId
    

    输出:

    UserId  DayOfLogDate
    1       9
    2       6
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-17
      • 2013-10-22
      • 2012-08-05
      • 1970-01-01
      • 2021-03-16
      • 1970-01-01
      • 1970-01-01
      • 2012-06-05
      相关资源
      最近更新 更多