SQL 按列组排列的行数
SQL rownumber by columngroup
我正在尝试创建工作活动报告。其中设置了以下条件。
如果有人在后续日期范围内缺席,则标记为同一缺席组,否则标记为新缺席组。
所以,如果我星期一、星期二、星期三缺席,那就是一组,用 1 标记。
如果我星期四上班,但星期五又不在,则星期五标记为group2。
如果下周一我还是缺席,那还是第2组。
提供的示例数据是我从我拥有的排班表中获得的数据类型,如果特定 activity 不存在或不存在则标识符除外。当然,在任何一天都有不止一组首字母缩写,以及不同类型的活动和缺席活动。
我已尝试提供输入数据和所需结果的最小工作示例。希望我能得到一些指示。
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')
这给了我想要的东西,但是当引入新组时,我无法重置行号、等级或 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
预期结果 - 全部工作 activity 日期范围
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]
使用 with (common table expression)
and row_number()
我们可以为分区 (Initials, activitytype)
和 (Initials)
生成行号。
通过比较它们,我们可以按 activity 对连续块进行分组,并使用 dense_rank()
对它们进行编号。
要将所有 'Work' 转换为 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 |
+------------+----------+-----------------+--------------+---------------+
我正在尝试创建工作活动报告。其中设置了以下条件。
如果有人在后续日期范围内缺席,则标记为同一缺席组,否则标记为新缺席组。
所以,如果我星期一、星期二、星期三缺席,那就是一组,用 1 标记。
如果我星期四上班,但星期五又不在,则星期五标记为group2。
如果下周一我还是缺席,那还是第2组。
提供的示例数据是我从我拥有的排班表中获得的数据类型,如果特定 activity 不存在或不存在则标识符除外。当然,在任何一天都有不止一组首字母缩写,以及不同类型的活动和缺席活动。
我已尝试提供输入数据和所需结果的最小工作示例。希望我能得到一些指示。
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')
这给了我想要的东西,但是当引入新组时,我无法重置行号、等级或 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
预期结果 - 全部工作 activity 日期范围
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]
使用 with (common table expression)
and row_number()
我们可以为分区 (Initials, activitytype)
和 (Initials)
生成行号。
通过比较它们,我们可以按 activity 对连续块进行分组,并使用 dense_rank()
对它们进行编号。
要将所有 'Work' 转换为 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 |
+------------+----------+-----------------+--------------+---------------+