两个日期之间每天未结订单的 SQL 计数
Posted
技术标签:
【中文标题】两个日期之间每天未结订单的 SQL 计数【英文标题】:SQL Count Of Open Orders Each Day Between Two Dates 【发布时间】:2012-06-26 14:23:19 【问题描述】:我尝试过搜索,但我可能使用了错误的关键字,因为我找不到答案。
我正在尝试查找在两个日期之间以及按员工打开的订单数量。我有一个显示员工列表的表,另一个显示包含打开和关闭日期的订单列表以及日期表(如果有帮助的话)。
加入的员工和订单表将返回如下内容:
employee order ref opened closed
a 123 01/01/2012 04/01/2012
b 124 02/01/2012 03/01/2012
a 125 02/01/2012 03/01/2012
我需要将这些数据转换成:
Date employee Count
01/01/2012 a 1
02/01/2012 a 2
02/01/2012 b 1
03/01/2012 a 2
03/01/2012 b 1
04/01/2012 a 1
我正在从 SQL 服务器中提取数据。
有什么想法吗?
谢谢
尼克
【问题讨论】:
如果根本没有行,你需要它显示零吗? 【参考方案1】:将Dates
加入Employees
和Orders
之间的连接结果,然后按日期和员工分组以获得计数,如下所示:
SELECT
d.Date,
o.Employee,
COUNT(*) AS count
FROM Employees e
INNER JOIN Orders o ON e.ID = o.Employee
INNER JOIN Dates d ON d.Date BETWEEN o.Opened AND o.Closed
GROUP BY
d.Date,
o.Employee
【讨论】:
【参考方案2】:我最喜欢的方法是计算累积打开次数和累积关闭次数。
with cumopens as
(select employee, opened as thedate,
row_number() over (partition by employee order by opened) as cumopens,
0 as cumcloses
from eo
),
cumcloses as
(select employee, closed as thedate, 0 as cumopens,
row_number() over (partition by employee order by closed ) as cumcloses
from eo
)
select employee, c.thedate, max(cumopens), max(cumcloses),
max(cumopens) - max(cumcloses) as stillopened
from ((select *
from cumopens
) union all
(select *
from cumcloses
)
) c
group by employee, thedate
这种方法的唯一问题是只报告有员工活动的日期。这适用于您的情况。
更通用的解决方案需要一个序列号来生成日期。为此,我经常从一些具有足够行数的现有表中创建一个:
with nums as
(select row_number() over (partition by null order by null) as seqnum
from employees
)
select employee, dateadd(day, opened, seqnum) as thedate, count(*)
from eo join
nums
on datediff(day, opened, closed) < seqnum
group by employee, dateadd(day, opened, seqnum)
order by 1, 2
【讨论】:
不小心被否决了,现在我无法撤消了。对不起。【参考方案3】:SELECT opened,employee,count(*)
FROM employee LEFT JOIN orders
WHERE opened < firstDate and opened > secondDate
GROUP BY opened,employee
或者你可以改变第一个条件
WHERE opened BETWEEN firstDate and secondDate
【讨论】:
【参考方案4】:调用结果列计数有点奇怪,因为它实际上似乎是一个行号。 您可以通过使用 ROW_NUMBER 来做到这一点。
另一个有趣的部分是您还希望打开日期和关闭日期作为单独的行。使用一个简单的 UNION 就可以解决这个问题。
WITH cte
AS (SELECT Row_number() OVER ( PARTITION BY employee
ORDER BY order_ref) count,
employee,
opened,
closed
FROM orders)
SELECT employee, opened date, count
FROM cte
UNION ALL
SELECT employee, closed date, count
FROM cte
ORDER BY Date,
employee
DEMO
【讨论】:
以上是关于两个日期之间每天未结订单的 SQL 计数的主要内容,如果未能解决你的问题,请参考以下文章