我有一张如下表:
+----+----------------+-------------------------+
| id | employeeNumber | transactionTime |
+----+----------------+-------------------------+
| 1 | 1234 | 2016-02-23 15:11:00.000 |
+----+----------------+-------------------------+
| 2 | 1234 | 2016-02-22 11:01:00.000 |
+----+----------------+-------------------------+
| 3 | 1235 | 2016-02-22 07:22:00.000 |
+----+----------------+-------------------------+
| 4 | 1236 | 2016-02-20 09:16:00.000 |
+----+----------------+-------------------------+
| 5 | 1236 | 2016-02-19 11:01:00.000 |
+----+----------------+-------------------------+
| 6 | 1236 | 2016-02-18 11:44:00.000 |
+----+----------------+-------------------------+
| 7 | 1236 | 2016-02-17 12:12:00.000 |
+----+----------------+-------------------------+
| 8 | 1236 | 2016-02-16 11:09:00.000 |
+----+----------------+-------------------------+
| 9 | 1236 | 2016-02-15 11:19:00.000 |
+----+----------------+-------------------------+
| 10 | 1236 | 2016-02-14 09:12:00.000 |
+----+----------------+-------------------------+
我需要找到一种方法来返回每位员工在过去两周内记录交易的连续天数。比如这个:
+------+--------------+-------------------------+-------------------------+
| days |employeeNumber| startTime | endTime |
+------+--------------+-------------------------+-------------------------+
| 2 | 1234 | 2016-02-22 11:01:00.000 | 2016-02-23 15:11:00.000 |
+------+--------------+-------------------------+-------------------------+
| 1 | 1235 | 2016-02-22 11:01:00.000 | 2016-02-22 11:01:00.000 |
+------+--------------+-------------------------+-------------------------+
| 7 | 1236 | 2016-02-14 09:12:00.000 | 2016-02-20 09:16:00.000 |
+------+--------------+-------------------------+-------------------------+
我一直在使用以下查询,但它只返回一个用户,并且仅在过去两周内没有考虑。
WITH
dates(date) AS (
SELECT DISTINCT CAST(transactionTime AS DATE)
FROM Fuel.dbo.comdata
WHERE employeeNumber = 123456
),
groups AS (
SELECT ROW_NUMBER() OVER (ORDER BY date) AS rn,
DATEADD(DAY, -ROW_NUMBER() OVER (ORDER BY date), date) AS grp,
date
FROM dates
)
SELECT COUNT(*) AS consecutiveDates,
MIN(date) AS minDate, MAX(date) AS maxDate
FROM groups
GROUP BY grp
ORDER BY 1 DESC, 2 DESC
感谢任何帮助。
所以我发现以下查询非常有用,感谢Gordon Linoff在下面的回答。但是我注意到最小/最大日期与连续天数不匹配。如此处显示实时数据:
SELECT * FROM (
SELECT employeeNumber, COUNT(*) AS consecutiveDays,
MIN(transactionTime) AS startTime, MAX(transactionTime) AS endTime
FROM (
SELECT cd.*, DATEADD(DAY, -DENSE_RANK() OVER (PARTITION BY
employeeNumber ORDER BY transactionTime), CAST(transactionTime AS
DATE)) AS grp
FROM Fuel.dbo.comdata cd
WHERE transactionTime >= DATEADD(DAY, -14, GETDATE())
) cd
GROUP BY employeeNumber, grp
) AS tbl1
WHERE consecutiveDays >= 7
+--------------+-------------------------+------------------------+
| empNum | days| startTime | endTime |
+--------+-------------------------------+------------------------+
| 16742 | 7 | 2016-04-28 17:00:00.000 | 2016-05-07 17:04:00.000|
+--------+-------------------------------+------------------------+
| 15056 | 8 | 2016-04-27 13:03:00.000 | 2016-05-08 09:51:00.000|
+--------+-------------------------------+------------------------+
正如您所看到的,连续天数与开始/结束时间不匹配。有什么想法吗?
答案 0 :(得分:0)
我会使用行号方法来区分(假设每位员工每天的记录数不超过一条):
select employee, count(*) as numdays,
min(timestamp) as startTime, max(timestamp) as endTime
from (select cd.*,
dateadd(day,
- row_number() over (partition by employee order by transactionTime),
cast(transactionTime as date)
) as grp
from Fuel.dbo.comdata cd
) cd
group by employee, grp;
这个想法是根据transactionTime为每个员工生成一系列序列号。当事务处于连续的几天时,它与transactionTime之间的差异是不变的。
如果您可以在同一天进行多笔交易,则可以使用dense_rank()
。
如果您在同一天有重复项:
select employee, count(*) as numdays,
min(timestamp) as startTime, max(timestamp) as endTime
from (select cd.*,
dateadd(day,
- dense_rank() over (partition by employee order by cast(transactionTime as date)),
cast(transactionTime as date)
) as grp
from Fuel.dbo.comdata cd
) cd
group by employee, grp;