【问题标题】:Microsoft SQL Server 2016 - T-SQL language - 'Gaps & Islands' problem - tricky partitionMicrosoft SQL Server 2016 - T-SQL 语言 - “差距和孤岛”问题 - 棘手的分区
【发布时间】:2022-01-06 16:17:14
【问题描述】:

我有 5 名员工,他们的 ID 值为:111、222、333、444、555。

我有一个源数据集,其中包含 2021 年 3 月 28 日至 2021 年 4 月 5 日之间所有日历日所有五个人的数据。(这只是我实际数据的一小部分样本子集)。

您可以使用这些脚本查看源数据的示例:

CREATE TABLE #SourceDataset
(
    EmployeeId int,
    PayGroupName varchar(100),
    PayTypeName varchar(100),
    SiteName varchar(100),
    Region varchar(100),
    PercentageScore int,
    Center int,
    [Function] varchar(100),
    Department varchar(100),
    EverySingleCalendarDate date
)

--- for Employee ID = 111 ---

INSERT INTO #SourceDataset
VALUES (111, 'Biweekly', 'Salaried', 'Shop Floor', 'NYC', 100, 17, 'WQ', 'FG', '3/28/2021'),
       (111, 'Biweekly', 'Salaried', 'Shop Floor', 'NYC', 100, 17, 'WQ', 'FG', '3/29/2021'),
       (111, 'Biweekly', 'Salaried', 'Shop Floor', 'NYC', 100, 17, 'WQ', 'FG', '3/30/2021'),
       (111, 'Biweekly', 'Salaried', 'Shop Floor', 'NYC', 100, 17, 'WQ', 'FG', '3/31/2021'),
       (111, 'Biweekly', 'Salaried', 'Shop Floor', 'NYC', 100, 17, 'WQ', 'FG', '4/1/2021'),
       (111, 'Biweekly', 'Salaried', 'Shop Floor', 'NYC', 50, 56, 'WQ', 'FG', '4/2/2021'),
       (111, 'Biweekly', 'Salaried', 'Shop Floor', 'NYC', 50, 80, 'WQ', 'FG', '4/2/2021'),
       (111, 'Biweekly', 'Salaried', 'Shop Floor', 'NYC', 50, 56, 'WQ', 'FG', '4/3/2021'),
(111,   'Biweekly', 'Salaried', 'Shop Floor',   'NYC',  50, 80, 'WQ',   'FG',   '4/3/2021'),
(111,   'Biweekly', 'Salaried', 'Shop Floor',   'NYC',  50, 56, 'WQ',   'FG',   '4/4/2021'),
(111,   'Biweekly', 'Salaried', 'Shop Floor',   'NYC',  50, 80, 'WQ',   'FG',   '4/4/2021'),
(111,   'Biweekly', 'Salaried', 'Shop Floor',   'NYC',  50, 56, 'WQ',   'FG',   '4/5/2021'),
(111,   'Biweekly', 'Salaried', 'Shop Floor',   'NYC',  50, 80, 'WQ',   'FG',   '4/5/2021')

--- for Employee ID = 111 ---

--- for Employee ID = 222 ---

INSERT INTO #SourceDataset

VALUES

(222,   'Monthly',  'PartTime', 'Office Room',  'POR',  100,    19, 'WQ',   'FG',   '3/28/2021'),
(222,   'Monthly',  'PartTime', 'Office Room',  'POR',  100,    19, 'WQ',   'FG',   '3/29/2021'),
(222,   'Monthly',  'PartTime', 'Office Room',  'POR',  100,    19, 'WQ',   'FG',   '3/30/2021'),
(222,   'Monthly',  'PartTime', 'Office Room',  'POR',  100,    20, 'WR',   'FY',   '3/31/2021'),
(222,   'Monthly',  'PartTime', 'Office Room',  'POR',  100,    20, 'WR',   'FY',   '4/1/2021'),
(222,   'Monthly',  'PartTime', 'Office Room',  'POR',  25, 19, 'RH',   'FG',   '4/2/2021'),
(222,   'Monthly',  'PartTime', 'Office Room',  'POR',  75, 19, 'DP',   'FG',   '4/2/2021'),
(222,   'Monthly',  'PartTime', 'Office Room',  'POR',  25, 19, 'RH',   'FG',   '4/3/2021'),
(222,   'Monthly',  'PartTime', 'Office Room',  'POR',  75, 19, 'DP',   'FG',   '4/3/2021'),
(222,   'Monthly',  'PartTime', 'Office Room',  'POR',  100,    19, 'WQ',   'FG',   '4/4/2021'),
(222,   'Monthly',  'PartTime', 'Office Room',  'POR',  100,    19, 'WQ',   'FG',   '4/5/2021')

--- for Employee ID = 222 ---

--- for Employee ID = 333 ---

INSERT INTO #SourceDataset

VALUES

(333, 'Weekly',    'Contract',  'Store',    'ATL',  100,    19, 'WQ',   'FG',   '3/28/2021'),
(333, 'Weekly PT', 'Contract',  'Store',    'ATL',  100,    19, 'WQ',   'FG',   '3/29/2021'),
(333, 'Weekly PT', 'Temporary', 'Store',    'ATL',  100,    19, 'WQ',   'FG',   '3/30/2021'),
(333, 'Weekly',    'Contract',  'Store',    'ATL',  100,    19, 'WQ',   'FG',   '3/31/2021'),
(333, 'Weekly',    'Contract',  'Store',    'ATL',  100,    19, 'WQ',   'FG',   '4/1/2021'),
(333, 'Weekly',    'Contract',  'Store',    'ATL',  40, 19, 'WQ',   'PQ',   '4/2/2021'),
(333, 'Weekly',    'Contract',  'Store',    'ATL',  60, 19, 'WQ',   'AD',   '4/2/2021'),
(333, 'Weekly',    'Contract',  'Store',    'ATL',  40, 19, 'WQ',   'PQ',   '4/3/2021'),
(333, 'Weekly',    'Contract',  'Store',    'ATL',  60, 19, 'WQ',   'AD',   '4/3/2021'),
(333, 'Weekly',    'Contract',  'Store',    'ATL',  40, 19, 'WQ',   'PQ',   '4/4/2021'),
(333, 'Weekly',    'Contract',  'Store',    'ATL',  60, 19, 'WQ',   'AD',   '4/4/2021'),
(333, 'Weekly',    'Contract',  'Store',    'ATL',  40, 19, 'WQ',   'PQ',   '4/5/2021'),
(333, 'Weekly',    'Contract',  'Store',    'ATL',  60, 19, 'WQ',   'AD',   '4/5/2021')

--- for Employee ID = 333 ---

--- for Employee ID = 444 ---

INSERT INTO #SourceDataset

VALUES

(444,   'Weekly',   'FT',           'StoreHouse',   'MIA',  100,    19, 'WQ',   'FG',   '3/28/2021'),
(444,   'Weekly',   'FT-Optional',  'StoreHouse',   'MIA',  100,    19, 'WQ',   'FG',   '3/29/2021'),
(444,   'Weekly',   'FT-Optional',  'StoreHouse',   'MIA',  100,    19, 'WQ',   'FG',   '3/30/2021'),
(444,   'Weekly',   'FT',           'StoreHouse',   'MIA',  100,    19, 'WQ',   'FG',   '3/31/2021'),
(444,   'Weekly',   'FT',           'StoreHouse',   'MIA',  100,    19, 'WQ',   'FG',   '4/1/2021'),
(444,   'Weekly',   'FT',           'StoreHouse',   'MIA',  50, 10, 'AB',   'FG',   '4/2/2021'),
(444,   'Weekly',   'FT',           'StoreHouse',   'MIA',  50, 11, 'HP',   'FG',   '4/2/2021'),
(444,   'Weekly',   'FT',           'StoreHouse',   'MIA',  50, 10, 'AB',   'FG',   '4/3/2021'),
(444,   'Weekly',   'FT',           'StoreHouse',   'MIA',  50, 11, 'HP',   'FG',   '4/3/2021'),
(444,   'Weekly',   'FT',           'StoreHouse',   'MIA',  65, 29, 'RR',   'FG',   '4/4/2021'),
(444,   'Weekly',   'FT',           'StoreHouse',   'MIA',  35, 37, 'QQ',   'FG',   '4/4/2021'),
(444,   'Weekly',   'FT',           'StoreHouse',   'MIA',  50, 10, 'AB',   'FG',   '4/5/2021'),
(444,   'Weekly',   'FT',           'StoreHouse',   'MIA',  50, 11, 'HP',   'FG',   '4/5/2021')

--- for Employee ID = 444 ---

--- for Employee ID = 555 ---

INSERT INTO #SourceDataset

VALUES

(555,   'Weekly',                   'FT',   'StoreHouse1',    'RIC',    100,    19, 'WQ',   'FG',   '3/28/2021'),
(555,   'WeeklyOptional',           'PT',   'StoreHouse2',    'RIC',    100,    19, 'WQ',   'FG',   '3/29/2021'),
(555,   'Weekly',                   'FT',   'StoreHouse1',    'RIC',    100,    19, 'WQ',   'FG',   '3/30/2021'),
(555,   'Weekly',                   'FT',   'StoreHouse1',    'RIC',    100,    19, 'WQ',   'FG',   '3/31/2021'),
(555,   'Weekly',                   'FT',   'StoreHouse1',    'RIC',    100,    19, 'WQ',   'FG',   '4/1/2021'),
(555,   'Weekly',                   'FT',   'StoreHouse1',    'RIC',    40, 23, 'BB',   'MA',   '4/2/2021'),
(555,   'Weekly',                   'FT',   'StoreHouse1',    'RIC',    25, 24, 'CV',   'RU',   '4/2/2021'),
(555,   'Weekly',                   'FT',   'StoreHouse1',    'RIC',    35, 25, 'FJ',   'BN',   '4/2/2021'),
(555,   'Weekly',                   'FT',   'StoreHouse1',    'RIC',    40, 23, 'BB',   'MA',   '4/3/2021'),
(555,   'Weekly',                   'FT',   'StoreHouse1',    'RIC',    25, 24, 'CV',   'RU',   '4/3/2021'),
(555,   'Weekly',                   'FT',   'StoreHouse1',    'RIC',    35, 25, 'FJ',   'BN',   '4/3/2021'),
(555,   'Weekly-NonOptional',           'FT',   'StoreHouse156',  'RIC',    33, 23, 'BB',   'MA',   '4/4/2021'),
(555,   'Weekly-NonOptional',           'FT',   'StoreHouse156',  'RIC',    33, 24, 'CV',   'RU',   '4/4/2021'),
(555,   'Weekly-NonOptional',           'FT',   'StoreHouse156',  'RIC',    34, 25, 'FJ',   'BN',   '4/4/2021'),
(555,   'Weekly',                   'FT',   'StoreHouse1',    'RIC',    40, 23, 'BB',   'MA',   '4/5/2021'),
(555,   'Weekly',                   'FT',   'StoreHouse1',    'RIC',    25, 24, 'CV',   'RU',   '4/5/2021'),
(555,   'Weekly',                   'FT',   'StoreHouse1',    'RIC',    35, 25, 'FJ',   'BN',   '4/5/2021')

--- for Employee ID = 555 ---

SELECT *
FROM #SourceDataset
ORDER BY EmployeeId, EverySingleCalendarDate

---------------------------------------------------

目标:我正在尝试跟踪员工如何在一段时间内达到 100 % 的百分比分数,并开发组以显示此信息,并使用新的 MinDate 和 MaxDate 列,显示组存在的日期范围。在此处提到的时间段(2021 年 3 月 28 日 - 2021 年 4 月 5 日)内,任何员工的日历天数都没有间隔。

关于源数据集的注释:

员工可以在给定日历日的一行中获得 100% 的百分比分数,每个列下都有一个唯一值 - 中心、职能、部门。或者,她可能在另一个日历日达到 100 % 百分比分数,这 3 列的不同组合 - 中心、功能、部门 - 在多行中,按百分比拆分 分数(例如,三行 40 + 25 + 35(或)两行 50 + 50),该日历日的总分为 100%。请参阅源数据集上的示例查询以了解我的意思。

源数据集的开发方式是 - 每个日历日必须占任何员工的 100%,并且日历日​​之间没有间隔。对于员工,这 4 列(PayGroupName、PayTypeName、SiteName、Region)的更改仅发生在日历日级别,而不是 PercentageScore 列级别或 Center、Function、Department 列级别。

Example:

SELECT *
FROM #SourceDataset
WHERE EmployeeId = 111
AND EverySingleCalendarDate = '2021-03-28'
--100 % Percentage Score in one row--

SELECT *
FROM #SourceDataset
WHERE EmployeeId = 111
AND EverySingleCalendarDate = '2021-04-02'
--100 % Percentage Score in two rows (50 + 50)--

SELECT *
FROM #SourceDataset
WHERE EmployeeId = 555
AND EverySingleCalendarDate = '2021-04-02'
--100 % Percentage Score in three rows (40 + 25 + 35)--

我的目标是跟踪每位员工在一段时间内(从 3 月 28 日到 4 月 5 日)如何达到 100 % 的百分比分数,这些天我所有 5 名员工的数据都可用,日历中没有间隔源数据集中的天数。

员工在给定日历日的行数取决于她如何达到 100 % 百分比分数,或者在一行中 或多行。 “行数”(任何员工的日历日)基本上取决于 3 列的集合 - 中心、职能、部门。

另一点很重要:PayGroupName、PayTypeName、SiteName、Region 列在给定日历日对于员工来说总是有一个唯一值。因此,给定日历上员工的行数不是由这些列决定的 - PayGroupName、PayTypeName、SiteName、Region。

也就是说,每个列(PayGroupName、PayTypeName、SiteName、Region)下的数据可能会在员工的日历日之间发生变化,我们也需要对此进行跟踪。请参阅下面对源数据集的示例查询:

SELECT *
FROM #SourceDataset
WHERE EmployeeId = 333
AND EverySingleCalendarDate BETWEEN '2021-03-28' AND '2021-03-30'
--PayGroupName and PayTypeName change between days for this employee (333)--

SELECT *
FROM #SourceDataset
WHERE EmployeeId = 555
AND EverySingleCalendarDate BETWEEN '2021-04-03' AND '2021-04-04'
/*
PayGroupName and SiteName change between days for this employee (555);
and its' very important to to note that for an employee, the change for these 4 columns
(PayGroupName, PayTypeName, SiteName, Region) can happen only at the calendar day level, NOT at the
level of Percentage Score or at the level of the columns - Center, Function, Department.

In essence, the change for these 4 columns (PayGroupName, PayTypeName, SiteName, Region) for an
employee can happen ONLY at the level of a calendar day.
*/

几周前,我在同一个topic 上发布了一个问题,但数据集更简单,在任何给定的日历日,员工都只有一行。

今天,我遇到了一个类似但具有挑战性的情况,其中一个员工在给定的日历日可能有多行。这取决于员工(例如员工 ID = 111)如何获得 100 % 百分比分数,对于一个日历日,例如 2021 年 3 月 28 日。

我有所需的输出数据集,既可以作为使用 T-SQL 的临时表,也可以作为表格输出,这样您就可以清楚地了解我手头的问题。

所需的输出:

CREATE TABLE #DesiredOutput

(

EmployeeId int,
PayGroupName varchar(100),
PayTypeName varchar(100),
SiteName varchar(100),
Region varchar(100),
PercentageScore int,
Center int,
[Function] varchar(100),
Department varchar(100),
MinDate date,
MaxDate date

)


INSERT INTO #DesiredOutput

VALUES


(111,   'Biweekly',         'Salaried', 'Shop Floor',    'NYC', 100,    17, 'WQ',   'FG',   '3/28/2021',    '4/1/2021'),
(111,   'Biweekly',         'Salaried', 'Shop Floor',    'NYC', 50, 56, 'WQ',   'FG',   '4/2/2021', '4/5/2021'),
(111,   'Biweekly',         'Salaried', 'Shop Floor',    'NYC', 50, 80, 'WQ',   'FG',   '4/2/2021', '4/5/2021'),
(222,   'Monthly',              'PartTime', 'Office Room',   'POR', 100,    19, 'WQ',   'FG',   '3/28/2021',    '3/30/2021'),
(222,   'Monthly',          'PartTime', 'Office Room',   'POR', 100,    20, 'WR',   'FY',   '3/31/2021',    '4/1/2021'),
(222,   'Monthly',          'PartTime', 'Office Room',   'POR', 25, 19, 'RH',   'FG',   '4/2/2021', '4/3/2021'),
(222,   'Monthly',              'PartTime', 'Office Room',   'POR', 75, 19, 'DP',   'FG',   '4/2/2021', '4/3/2021'),
(222,   'Monthly',          'PartTime', 'Office Room',   'POR', 100,    19, 'WQ',   'FG',   '4/4/2021', '4/5/2021'),
(333,   'Weekly',           'Contract', 'Store',     'ATL', 100,    19, 'WQ',   'FG',   '3/28/2021',    '3/28/2021'),
(333,   'Weekly PT',            'Contract', 'Store',     'ATL', 100,    19, 'WQ',   'FG',   '3/29/2021',    '3/29/2021'),
(333,   'Weekly PT',            'Temporary',    'Store',         'ATL', 100,    19, 'WQ',   'FG',   '3/30/2021',    '3/30/2021'),
(333,   'Weekly',           'Contract', 'Store',         'ATL', 100,    19, 'WQ',   'FG',   '3/31/2021',    '4/1/2021'),
(333,   'Weekly',           'Contract', 'Store',     'ATL', 40, 19, 'WQ',   'PQ',   '4/2/2021', '4/5/2021'),
(333,   'Weekly',           'Contract', 'Store',     'ATL', 60, 19, 'WQ',   'AD',   '4/2/2021', '4/5/2021'),
(444,   'Weekly',           'FT',           'StoreHouse',    'MIA', 100,    19, 'WQ',   'FG',   '3/28/2021',    '3/28/2021'),
(444,   'Weekly',           'FT-Optional',  'StoreHouse',    'MIA', 100,    19, 'WQ',   'FG',   '3/29/2021',    '3/30/2021'),
(444,   'Weekly',           'FT',           'StoreHouse',    'MIA', 100,    19, 'WQ',   'FG',   '3/31/2021',    '4/1/2021'),
(444,   'Weekly',           'FT',           'StoreHouse',    'MIA', 50, 10, 'AB',   'FG',   '4/2/2021', '4/3/2021'),
(444,   'Weekly',           'FT',           'StoreHouse',    'MIA', 50, 11, 'HP',   'FG',   '4/2/2021', '4/3/2021'),
(444,   'Weekly',           'FT',           'StoreHouse',    'MIA', 65, 29, 'RR',   'FG',   '4/4/2021', '4/4/2021'),
(444,   'Weekly',           'FT',           'StoreHouse',    'MIA', 35, 37, 'QQ',   'FG',   '4/4/2021', '4/4/2021'),
(444,   'Weekly',           'FT',           'StoreHouse',    'MIA', 50, 10, 'AB',   'FG',   '4/5/2021', '4/5/2021'),
(444,   'Weekly',           'FT',           'StoreHouse',    'MIA', 50, 11, 'HP',   'FG',   '4/5/2021', '4/5/2021'),
(555,   'Weekly',           'FT',           'StoreHouse1',   'RIC', 100,    19, 'WQ',   'FG',   '3/28/2021',    '3/28/2021'),
(555,   'WeeklyOptional',   'PT',           'StoreHouse2',   'RIC', 100,    19, 'WQ',   'FG',   '3/29/2021',    '3/29/2021'),
(555,   'Weekly',           'FT',           'StoreHouse1',   'RIC', 100,    19, 'WQ',   'FG',   '3/30/2021',    '4/1/2021'),
(555,   'Weekly',           'FT',           'StoreHouse1',   'RIC', 40, 23, 'BB',   'MA',   '4/2/2021', '4/3/2021'),
(555,   'Weekly',           'FT',           'StoreHouse1',   'RIC', 25, 24, 'CV',   'RU',   '4/2/2021', '4/3/2021'),
(555,   'Weekly',           'FT',           'StoreHouse1',   'RIC', 35, 25, 'FJ',   'BN',   '4/2/2021', '4/3/2021'),
(555,   'Weekly-NonOptional',   'FT',           'StoreHouse156', 'RIC', 33, 23, 'BB',   'MA',   '4/4/2021', '4/4/2021'),
(555,   'Weekly-NonOptional',   'FT',           'StoreHouse156', 'RIC', 33, 24, 'CV',   'RU',   '4/4/2021', '4/4/2021'),
(555,   'Weekly-NonOptional',   'FT',           'StoreHouse156', 'RIC', 34, 25, 'FJ',   'BN',   '4/4/2021', '4/4/2021'),
(555,   'Weekly',           'FT',           'StoreHouse1',   'RIC', 40, 23, 'BB',   'MA',   '4/5/2021', '4/5/2021'),
(555,   'Weekly',           'FT',           'StoreHouse1',   'RIC', 25, 24, 'CV',   'RU',   '4/5/2021', '4/5/2021'),
(555,   'Weekly',           'FT',           'StoreHouse1',   'RIC', 35, 25, 'FJ',   'BN',   '4/5/2021', '4/5/2021')



SELECT *
FROM #DesiredOutput
ORDER BY EmployeeId, MinDate

我需要使用#SourceDataset 并将其转换为#DesiredOutput。

我需要一些建议。

例如,#DesiredOutput(表格形式)对于员工 (111) 和所有员工如下所示:

EmployeeId PayGroupName PayTypeName SiteName Region PercentageScore Center Function Department MinDate MaxDate
111 Biweekly Salaried Shop Floor NYC 100 17 WQ FG 3/28/2021 4/1/2021
111 Biweekly Salaried Shop Floor NYC 50 56 WQ FG 4/2/2021 4/5/2021
111 Biweekly Salaried Shop Floor NYC 50 80 WQ FG 4/2/2021 4/5/2021
EmployeeId PayGroupName PayTypeName SiteName Region PercentageScore Center Function Department MinDate MaxDate
111 Biweekly Salaried Shop Floor NYC 100 17 WQ FG 3/28/2021 4/1/2021
111 Biweekly Salaried Shop Floor NYC 50 56 WQ FG 4/2/2021 4/5/2021
111 Biweekly Salaried Shop Floor NYC 50 80 WQ FG 4/2/2021 4/5/2021
222 Monthly PartTime Office Room POR 100 19 WQ FG 3/28/2021 3/30/2021
222 Monthly PartTime Office Room POR 100 20 WR FY 3/31/2021 4/1/2021
222 Monthly PartTime Office Room POR 25 19 RH FG 4/2/2021 4/3/2021
222 Monthly PartTime Office Room POR 75 19 DP FG 4/2/2021 4/3/2021
222 Monthly PartTime Office Room POR 100 19 WQ FG 4/4/2021 4/5/2021
333 Weekly Contract Store ATL 100 19 WQ FG 3/28/2021 3/28/2021
333 WeeklyPT Contract Store ATL 100 19 WQ FG 3/29/2021 3/29/2021
333 WeeklyPT Temporary Store ATL 100 19 WQ FG 3/30/2021 3/30/2021
333 Weekly Contract Store ATL 100 19 WQ FG 3/31/2021 4/1/2021
333 Weekly Contract Store ATL 40 19 WQ PQ 4/2/2021 4/5/2021
333 Weekly Contract Store ATL 60 19 WQ AD 4/2/2021 4/5/2021
444 Weekly FT StoreHouse MIA 100 19 WQ FG 3/28/2021 3/28/2021
444 Weekly FT-Optional StoreHouse MIA 100 19 WQ FG 3/29/2021 3/30/2021
444 Weekly FT StoreHouse MIA 100 19 WQ FG 3/31/2021 4/1/2021
444 Weekly FT StoreHouse MIA 50 10 AB FG 4/2/2021 4/3/2021
444 Weekly FT StoreHouse MIA 50 11 HP FG 4/2/2021 4/3/2021
444 Weekly FT StoreHouse MIA 65 29 RR FG 4/4/2021 4/4/2021
444 Weekly FT StoreHouse MIA 35 37 QQ FG 4/4/2021 4/4/2021
444 Weekly FT StoreHouse MIA 50 10 AB FG 4/5/2021 4/5/2021
444 Weekly FT StoreHouse MIA 50 11 HP FG 4/5/2021 4/5/2021
555 Weekly FT StoreHouse1 RIC 100 19 WQ FG 3/28/2021 3/28/2021
555 WeeklyOptional PT StoreHouse2 RIC 100 19 WQ FG 3/29/2021 3/29/2021
555 Weekly FT StoreHouse1 RIC 100 19 WQ FG 3/30/2021 4/1/2021
555 Weekly FT StoreHouse1 RIC 40 23 BB MA 4/2/2021 4/3/2021
555 Weekly FT StoreHouse1 RIC 25 24 CV RU 4/2/2021 4/3/2021
555 Weekly FT StoreHouse1 RIC 35 25 FJ BN 4/2/2021 4/3/2021
555 Weekly-NonOPTional FT StoreHouse156 RIC 33 23 BB MA 4/4/2021 4/4/2021
555 Weekly-NonOPTional FT StoreHouse156 RIC 33 24 CV RU 4/4/2021 4/4/2021
555 Weekly-NonOPTional FT StoreHouse156 RIC 34 25 FJ BN 4/4/2021 4/4/2021
555 Weekly FT StoreHouse1 RIC 40 23 BB MA 4/5/2021 4/5/2021
555 Weekly FT StoreHouse1 RIC 25 24 CV RU 4/5/2021 4/5/2021
555 Weekly FT StoreHouse1 RIC 35 25 FJ BN 4/5/2021 4/5/2021

对如何开发所需的输出有任何想法吗?

下端的表格数据是全表,可能难以滚动;所以我在顶部有一个 Employee ID = 111 的较小版本,然后是整个所需的输出。或者,您可以使用 T-SQL 脚本了解#DesiredOutput 数据集。

【问题讨论】:

  • 鉴于您的问题的长度(比我有时间阅读的时间长),我不得不问这个问题,这是minimal reproducible example 即这是您可以解决的最简单的问题形式想出来吗?
  • @Dale K 这是一个相当复杂的,所以我觉得需要图像文件来描述
  • @Dale K 我已删除图像文件。你现在可以允许这个问题了吗?
  • 它仍然太不清楚和冗长。请注意minimal reproducible example 的minimal 部分,我们需要解释问题的所有信息,仅此而已。例如,您可以删除那些与问题无关的“静态”列。表格:见meta.stackoverflow.com/questions/277716/…
  • 不,我不会。我仍然无法理解你想要什么,因为这里有太多无关的信息让我无法吸收。您需要减少一个更简单的问题,并整理格式/段落

标签: sql-server tsql partition gaps-and-islands row-number


【解决方案1】:

使用的方法:

  • 计算标志以指示超过 1 天的间隔。
  • 根据对标志求和创建排名。
  • 将其分组,包括计算出的排名。
SELECT EmployeeId, PayGroupName, PayTypeName, SiteName, 
Region, PercentageScore,Center, [Function], Department
, MIN(EverySingleCalendarDate) MinDate
, MAX(EverySingleCalendarDate) MaxDate
INTO #tmpResults
FROM (
  SELECT *
  , Rnk = SUM(Flag) OVER (PARTITION BY EmployeeId, PayGroupName, PayTypeName, SiteName, 
Region, PercentageScore,Center, [Function], Department ORDER BY EverySingleCalendarDate)
  FROM
  (
     SELECT *
     , Flag = IIF(1=DATEDIFF(day, LAG(EverySingleCalendarDate) OVER (PARTITION BY EmployeeId, PayGroupName, PayTypeName, SiteName, 
Region, PercentageScore,Center, [Function], Department ORDER BY EverySingleCalendarDate), EverySingleCalendarDate),0,1)
     FROM #SourceDataset
  ) q1
) q2
GROUP BY EmployeeId, PayGroupName, PayTypeName, SiteName, 
Region, PercentageScore,Center, [Function], Department, Rnk
ORDER BY EmployeeId, MinDate;

SELECT * FROM #tmpResults;
--
-- Differences
--
SELECT * FROM #tmpResults
EXCEPT
SELECT * FROM #DesiredOutput;

SELECT * FROM #DesiredOutput
EXCEPT
SELECT * FROM #tmpResults;
GO
员工 ID |支付组名 |支付类型名称 |站点名称 |地区 |百分比分数 |中心 |功能 |部门 |最小日期 |最大日期 ---------: | :----------- | :------------ | :------- | :----- | --------------: | -----: | :------- | :--------- | :-------- | :------ 员工 ID |支付组名 |支付类型名称 |站点名称 |地区 |百分比分数 |中心 |功能 |部门 |最小日期 |最大日期 ---------: | :----------- | :------------ | :------- | :----- | --------------: | -----: | :------- | :--------- | :-------- | :------

db小提琴here

【讨论】:

  • 非常感谢;感谢你的帮助;正在研究您的解决方案;我会回来的
  • 我计划在本周晚些时候用我的完整数据集测试这个查询;希望在那之后我会标记您的答案;非常感谢。
  • 非常感谢,您的解决方案在我拥有的 2020 年和 2021 年的实际数据上运行良好。我将在接下来的几天内使用更多历史数据进行进一步测试,希望不会有问题.非常感谢您的帮助。
【解决方案2】:

这正是@LukStorms 提供的,但格式更好,以便任何人都可以使用此代码。非常感谢您的支持。

SELECT

k.EmployeeId,k.PayGroupName,k.PayTypeName,k.SiteName,k.Region,k.PercentageScore,k.Center,k.[Function],k.Department,

MIN(k.EverySingleCalendarDate) AS MinDate,
MAX(k.EverySingleCalendarDate) AS MaxDate

FROM

(

SELECT

g.*,

SUM(g.Flag) OVER

(

PARTITION BY

g.EmployeeId,g.PayGroupName,g.PayTypeName,g.SiteName,g.Region,g.PercentageScore,g.Center,g.[Function],g.Department

ORDER BY g.EverySingleCalendarDate

) AS Rnk

FROM
 
(

SELECT

*,

Flag = CASE

           WHEN DATEDIFF(dd,

                          LAG(EverySingleCalendarDate,1) OVER

                          (PARTITION BY

                          EmployeeId,PayGroupName,PayTypeName,SiteName,Region,PercentageScore,Center,[Function],Department

                          ORDER BY EverySingleCalendarDate),

                          EverySingleCalendarDate) = 1 THEN 0

            ELSE 1

        END

FROM 

#SourceDataset

) g

) k

GROUP BY

k.EmployeeId,k.PayGroupName,k.PayTypeName,k.SiteName,k.Region,k.PercentageScore,k.Center,k.[Function],k.Department,
k.Rnk
--note the Rnk column in the GROUP BY
--ORDER BY k.EmployeeId, MinDate

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多