columngroup

时间:2017-01-29 12:23:11

标签: sql-server ranking

我正在尝试创建工作活动报告。如果设置了以下条件。

如果在后续日期范围内缺席,则标记为相同的缺席组,否则标记为新缺席组。

所以,如果我在星期一,星期三,星期三不在,那么这就是一组,标记为1。

如果我当时在星期四工作,但星期五再次缺席,则星期五会以group2为标记。

如果我在下一个星期一仍然缺席那么那仍然是第2组。

提供的示例数据是我从班次调度表中获得的数据类型,除了标识符,如果特定活动是缺席或不缺席。当然,在任何一天都有不止一组的首字母,以及不同类型的活动和缺席活动。

我试图提供输入数据和期望结果的最小工作示例。希望我能对此有所了解。

USE Sandbox 
DROP TABLE Data /* Clean up after ourselves. */
CREATE TABLE Data ( /* Create table */
[Date] DATE,
Initials VARCHAR(10),
Activity VARCHAR(255),
ActivityType VARCHAR(255)
);

/* Insert data */
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-05','PersonA','Work','Work')
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-06','PersonA','Work','Work')
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-07','PersonA','AbsenceActivity','Absence')
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-08','PersonA','AbsenceActivity','Absence')
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-09','PersonA','AbsenceActivity','Absence')
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-10',NULL,NULL,'NoShift')
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-11',NULL,NULL,'NoShift')
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-12','PersonA','AbsenceActivity','Absence')
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-13','PersonA','Work','Work')
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-14','PersonA','AbsenceActivity','Absence')
INSERT INTO [dbo].[Data] ([Date],[Initials],[Activity],[ActivityType]) VALUES ('2016-12-15','PersonA','AbsenceActivity','Absence')

这种方式给了我想要的东西,但是当引入新组时,我无法让rownumber,rank或dense_rank重置。最终的期望结果。

    SELECT  [Date]
           ,Initials
           ,activity
           ,ActivityType
           ,rank() OVER (PARTITION BY data.activitytype, Initials ORDER BY data.date,data.initials) rownumber
    FROM    data
    GROUP BY data.date, data.initials, activity,ActivityType
ORDER BY date

期望的结果 - 完整的工作活动日期范围

SELECT '2016-12-05' as [Date]   ,'PersonA' AS [Initials]    ,'Work'             AS [Activity]   ,'Work'     AS [ActivityType]   ,'0' AS [identifier]    union all
SELECT '2016-12-06' as [Date]   ,'PersonA' AS [Initials]    ,'Work'             AS [Activity]   ,'Work'     AS [ActivityType]   ,'0' AS [identifier]    union all
SELECT '2016-12-07' as [Date]   ,'PersonA' AS [Initials]    ,'AbsenceActivity'  AS [Activity]   ,'Absence'  AS [ActivityType]   ,'1' AS [identifier]    union all
SELECT '2016-12-08' as [Date]   ,'PersonA' AS [Initials]    ,'AbsenceActivity'  AS [Activity]   ,'Absence'  AS [ActivityType]   ,'1' AS [identifier]    union all
SELECT '2016-12-09' as [Date]   ,'PersonA' AS [Initials]    ,'AbsenceActivity'  AS [Activity]   ,'Absence'  AS [ActivityType]   ,'1' AS [identifier]    union ALL
SELECT '2016-12-12' as [Date]   ,'PersonA' AS [Initials]    ,'AbsenceActivity'  AS [Activity]   ,'Absence'  AS [ActivityType]   ,'1' AS [identifier]    union all
SELECT '2016-12-13' as [Date]   ,'PersonA' AS [Initials]    ,'Work'             AS [Activity]   ,'Work'     AS [ActivityType]   ,'0' AS [identifier]    union all
SELECT '2016-12-14' as [Date]   ,'PersonA' AS [Initials]    ,'AbsenceActivity'  AS [Activity]   ,'Absence'  AS [ActivityType]   ,'2' AS [identifier]    union all
SELECT '2016-12-15' as [Date]   ,'PersonA' AS [Initials]    ,'AbsenceActivity'  AS [Activity]   ,'Absence'  AS [ActivityType]   ,'2' AS [identifier]    

替代结果1完整日期范围包括周期或非工作日期

SELECT '2016-12-05' as [Date]   ,'PersonA' AS [Initials]    ,'Work'             AS [Activity]   ,'Work'     AS [ActivityType]   ,'0' AS [identifier]    union all
SELECT '2016-12-06' as [Date]   ,'PersonA' AS [Initials]    ,'Work'             AS [Activity]   ,'Work'     AS [ActivityType]   ,'0' AS [identifier]    union all
SELECT '2016-12-07' as [Date]   ,'PersonA' AS [Initials]    ,'AbsenceActivity'  AS [Activity]   ,'Absence'  AS [ActivityType]   ,'1' AS [identifier]    union all
SELECT '2016-12-08' as [Date]   ,'PersonA' AS [Initials]    ,'AbsenceActivity'  AS [Activity]   ,'Absence'  AS [ActivityType]   ,'1' AS [identifier]    union all
SELECT '2016-12-09' as [Date]   ,'PersonA' AS [Initials]    ,'AbsenceActivity'  AS [Activity]   ,'Absence'  AS [ActivityType]   ,'1' AS [identifier]    union ALL
SELECT '2016-12-10' as [Date]   ,NULL       AS [Initials]   ,'Weekend'  AS [Activity]   ,'noShift' AS [ActivityType]    ,NULL AS [identifier]   union ALL
SELECT '2016-12-11' as [Date]   ,NULL       AS [Initials]   ,'Weekend' AS [Activity]    ,'noShift' AS [ActivityType]    ,NULL AS [identifier]   union ALL
SELECT '2016-12-12' as [Date]   ,'PersonA' AS [Initials]    ,'AbsenceActivity'  AS [Activity]   ,'Absence'  AS [ActivityType]   ,'1' AS [identifier]    union all
SELECT '2016-12-13' as [Date]   ,'PersonA' AS [Initials]    ,'Work'             AS [Activity]   ,'Work'     AS [ActivityType]   ,'0' AS [identifier]    union all
SELECT '2016-12-14' as [Date]   ,'PersonA' AS [Initials]    ,'AbsenceActivity'  AS [Activity]   ,'Absence'  AS [ActivityType]   ,'2' AS [identifier]    union all
SELECT '2016-12-15' as [Date]   ,'PersonA' AS [Initials]    ,'AbsenceActivity'  AS [Activity]   ,'Absence'  AS [ActivityType]   ,'2' AS [identifier]    

替代结果2仅包括一组首字母有活动的日期

SELECT '2016-12-07' as [Date]   ,'PersonA' AS [Initials]    ,'AbsenceActivity'  AS [Activity]   ,'Absence'  AS [ActivityType]   ,'1' AS [identifier]    union all
SELECT '2016-12-08' as [Date]   ,'PersonA' AS [Initials]    ,'AbsenceActivity'  AS [Activity]   ,'Absence'  AS [ActivityType]   ,'1' AS [identifier]    union all
SELECT '2016-12-09' as [Date]   ,'PersonA' AS [Initials]    ,'AbsenceActivity'  AS [Activity]   ,'Absence'  AS [ActivityType]   ,'1' AS [identifier]    union all
SELECT '2016-12-10' as [Date]   ,NULL AS [Initials] ,'Weekend'  AS [Activity]   ,'noShift' AS [ActivityType]    ,NULL AS [identifier]   union ALL
SELECT '2016-12-11' as [Date]   ,NULL AS [Initials] ,'Weekend' AS [Activity]    ,'noShift' AS [ActivityType]    ,NULL AS [identifier]   union ALL
SELECT '2016-12-12' as [Date]   ,'PersonA' AS [Initials]    ,'AbsenceActivity'  AS [Activity]   ,'Absence'  AS [ActivityType]   ,'1' AS [identifier]    union all
SELECT '2016-12-14' as [Date]   ,'PersonA' AS [Initials]    ,'AbsenceActivity'  AS [Activity]   ,'Absence'  AS [ActivityType]   ,'2' AS [identifier]    union all
SELECT '2016-12-15' as [Date]   ,'PersonA' AS [Initials]    ,'AbsenceActivity'  AS [Activity]   ,'Absence'  AS [ActivityType]   ,'2' AS [identifier]    

1 个答案:

答案 0 :(得分:1)

使用with (common table expression)row_number(),我们可以为分区(Initials, activitytype)(Initials)生成行号。

通过比较这些,我们可以按活动对连续的块进行分组,并使用dense_rank()对它们进行编号。

转换所有工作'至0我在最终查询中使用了case表达式。

rextester:http://rextester.com/AYR27547

with cte as (
  select  
        [Date]
      , Initials
      , activity
      , ActivityType
      , irn=row_number() over (
          partition by Initials 
          order by [date]
          )
      , atrn=row_number() over (
          partition by Initials, activitytype 
          order by [date]
          )
    from [data] d
    group by [Date], Initials, Activity, ActivityType
    )

select 
      [date]
    , Initials
    , activity
    , ActivityType
    , ActivityGroup = case 
        when ActivityType='Work' 
          then 0 
        else dense_rank() over (
            partition by Initials, ActivityType 
            order by irn-atrn
            )
        end
  from cte
  order by [date]

结果:

+------------+----------+-----------------+--------------+---------------+
|    date    | Initials |    activity     | ActivityType | ActivityGroup |
+------------+----------+-----------------+--------------+---------------+
| 2016-12-05 | PersonA  | Work            | Work         |             0 |
| 2016-12-06 | PersonA  | Work            | Work         |             0 |
| 2016-12-07 | PersonA  | AbsenceActivity | Absence      |             1 |
| 2016-12-08 | PersonA  | AbsenceActivity | Absence      |             1 |
| 2016-12-09 | PersonA  | AbsenceActivity | Absence      |             1 |
| 2016-12-10 | NULL     | NULL            | NoShift      |             1 |
| 2016-12-11 | NULL     | NULL            | NoShift      |             1 |
| 2016-12-12 | PersonA  | AbsenceActivity | Absence      |             1 |
| 2016-12-13 | PersonA  | Work            | Work         |             0 |
| 2016-12-14 | PersonA  | AbsenceActivity | Absence      |             2 |
| 2016-12-15 | PersonA  | AbsenceActivity | Absence      |             2 |
+------------+----------+-----------------+--------------+---------------+