【问题标题】:SQL Count Of Open Orders Each Day Between Two Dates两个日期之间每天未结订单的 SQL 计数
【发布时间】: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 服务器中提取数据。

有什么想法吗?

谢谢

尼克

【问题讨论】:

  • 如果根本没有行,你需要它显示零吗?

标签: sql sql-server


【解决方案1】:

Dates 加入EmployeesOrders 之间的连接结果,然后按日期和员工分组以获得计数,如下所示:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-08
        • 1970-01-01
        • 1970-01-01
        • 2012-10-28
        • 2019-04-12
        • 1970-01-01
        相关资源
        最近更新 更多