【问题标题】:How to get the count of Open workorders for a date range如何获取日期范围内未结工作订单的数量
【发布时间】:2016-08-02 06:01:25
【问题描述】:

工作订单表仅显示特定工作订单的当前状态,每当发生更改时,wostatus 表都有工作订单的历史记录。任何未处于“关闭”或“完成”状态的工作订单都被视为“打开” ”。

所以,我试图找出在特定日期(例如 2016 年 7 月 7 日)有多少工作订单处于打开状态,同样,每个优先级的给定范围内打开工作订单的数量。请检查示例输出。谢谢你,任何帮助都非常感谢......

表格:工人

 WoNum,     Priority,   UserID,         Status,             OpenDate,   Description,                            StatusDate, Location
 A17047,    12,         AD201685359,    WaitingMaterials,   30-Jun-16,  laptop fan not working,                 2-Jul-15,   HR
 A55198,    12,         AD201658376,    WaitingApproval,    01-Jul-16,  Need help with connecting two monitors, 1-Jul-16,   Finance
 A35508,    4,          AD201621226,    Close,              02-Jul-16,  Upgrade memory to 8GB,                  8-Jul-16,   Media

表格:wostatus

Wonum,  Status,             changedate, changedby
A17047, InProgress,         30-Jun-16,  AD201659555
A17047, Approved,           01-Jul-16,  AD201659555
A17047, WaitingMaterials,   02-Jul-15,  AD201659555
A55198, InProgress,         01-Jul-16,  AD201659555
A55198, WaitingApproval,    01-Jul-16,  AD201659555
A35508, InProgress,         02-Jul-16,  AD201659555
A35508, WaitingApproval,    02-Jul-16,  AD201659555
A35508, Approved,           03-Jul-16,  AD201659555
A35508, Complete,           08-Jul-16,  AD201659555
A35508, Close,              08-Jul-16,  AD201659555 

查询输出/希望输出看起来像这样

Date, Total P12 Open WorkOrders,Total P4 Open WorkOrders
 30-Jun-16    1    0
 01-Jul-16    2    0
 02-Jul-16    2    1
 03-Jul-16    2    1
 04-Jul-16    2    1
 05-Jul-16    2    1
 06-Jul-16    2    1
 07-Jul-16    2    1
 08-Jul-16    2    0

【问题讨论】:

  • 首先你需要一个日历/计数表。这是一个表(或视图或其他),其中包含您感兴趣的每一天的记录。考虑一下,还请添加适当的数据库标签(您实际上是指 SQLServer 吗?)
  • 另外请说明您是否可以选择创建数据库对象(即日历/计数表)。
  • 它是 SQL Server。我只有数据库的读取权限。
  • 感谢您的提示。使用日历表在 MS-Access 上尝试您的想法。
  • 我将添加 SQL Server 标记。你知道什么版本吗?

标签: sql sql-server count


【解决方案1】:

我们必须分批进行,在我知道某些部分有效之前,我无法给出完整的答案。工单表上没有截止日期,这很遗憾(而且出乎意料)。

首先是获取工作订单列表及其开始和结束日期。试试这个查询,看看它是否有效

-- Query 1: Get a list of work order with open and close dates
-- excluding WO's that were already closed before 1 Jan 2016

SELECT 
WO.WONum, 
WO.OpenDate, 
ISNULL(
    WC.CloseDate,
    CONVERT(DATE,'20990101',112)
) as CloseDate
FROM WorKOrder WO
LEFT OUTER JOIN 
(
SELECT WONum, MAX(ChangeDate) as CloseDate
FROM WorKOrder
WHERE Status IN ('Close','Complete')
GROUP BY WONum
) WC
ON WO.WONum = WC.WONum
-- Exclude altogether any work orders that were closed prior to 1 Jan 2016
-- As these should not appear in the report
WHERE NOT EXISTS (
    SELECT *
    FROM WorKOrder WAC
    WHERE Status IN ('Close','Complete')
    AND ChangeDate <= CONVERT(DATE,'20160101',112)
    AND WAC.WONum = WO.WONum
)

我假设WONum 在表WorkOrder 上是唯一的?此查询应列出所有工作订单及其打开和关闭日期。如果工作订单当前仍处于打开状态,我们将使用 2099 年 1 月 1 日的结束日期

第二个查询为我们提供了需要报告的所有日期。再次运行并确保它有效。另外请澄清我们在这里报告了多少天?一年?十个?

改编自http://blog.waynesheffield.com/wayne/code-library/virtual-tally-numbers-table/

-- Query 2: Tally/calendar table
;WITH
TENS (N)      AS (SELECT 0 UNION ALL SELECT 0 UNION ALL
                  SELECT 0 UNION ALL SELECT 0 UNION ALL
                  SELECT 0 UNION ALL SELECT 0 UNION ALL
                  SELECT 0 UNION ALL SELECT 0 UNION ALL
                  SELECT 0 UNION ALL SELECT 0),
THOUSANDS (N) AS (SELECT 1
                    FROM TENS t1
                         CROSS JOIN TENS t2
                         CROSS JOIN TENS t3),
TALLY (N)     AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0))
                    FROM THOUSANDS)
SELECT TOP 1000 DATEADD(d,N,CONVERT(DATE,'20151231',112)) ADate
FROM TALLY;

让这两个查询首先工作,然后我们将从那里开始。

最后的查询将这两者结合在一起。这还没有完成,但会为您提供日期列表,以及在该日期仍有多少工作订单处于打开状态。请试试这个。如果它不起作用,我们将对其进行调试。如果它确实有效,你必须测试你得到的数字。然后我们将添加P分解

-- Query 3: stick it all together
;WITH
TENS (N)      AS (SELECT 0 UNION ALL SELECT 0 UNION ALL
                  SELECT 0 UNION ALL SELECT 0 UNION ALL
                  SELECT 0 UNION ALL SELECT 0 UNION ALL
                  SELECT 0 UNION ALL SELECT 0 UNION ALL
                  SELECT 0 UNION ALL SELECT 0),
THOUSANDS (N) AS (SELECT 1
                    FROM TENS t1
                         CROSS JOIN TENS t2
                         CROSS JOIN TENS t3),
TALLY (N)     AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0))
                    FROM THOUSANDS)

SELECT 
WO.Priority,
CAL.D As IsOpenDate,
COUNT(*)
FROM WorKOrder WO
LEFT OUTER JOIN 
(
SELECT WONum, MAX(ChangeDate) as CloseDate
FROM WorKOrder
WHERE Status IN ('Close','Complete')
GROUP BY WONum
) WC
ON WO.WONum = WC.WONum
INNER JOIN 
(SELECT DATEADD(d,N,CONVERT(DATE,'20160101',112)) D FROM TALLY) CAL
ON CAL.D BETWEEN WO.OpenDate 
   AND   ISNULL(
            WC.CloseDate,
            CONVERT(DATE,'20990101',112)
         )
WHERE NOT EXISTS (
    SELECT *
    FROM WorKOrder WAC
    WHERE Status IN ('Close','Complete')
    AND ChangeDate <= CONVERT(DATE,'20160101',112)
    AND WAC.WONum = WO.WONum
)
GROUP BY CAL.D, WO.Priority

只需确认这是做什么的:针对 P4 的 1,000 个数字和 2016 年 8 月 27 日的日期意味着在该日期,P4 有 1,000 个工作订单在之前打开或 2016 年 8 月 27 日,尚未关闭。所以这是当天有多少工作订单打开的计数。这不是当天打开ed的数量。你不应该把这个数字加起来,你应该在非加法趋势图中使用它

如果您想查看构成此编号的 1,000 个单独的工作订单,请使用查询 1 并将其添加到末尾:

AND CONVERT(DATE,'20160827',112) BETWEEN WO.OpenDate 
       AND   ISNULL(
                WC.CloseDate,
                CONVERT(DATE,'20990101',112)
             )

【讨论】:

  • 第一个查询给了我一个错误,第二个查询没有任何错误。消息 102,级别 15,状态 1,第 6 行“20990101”附近的语法不正确。消息 105,级别 15,状态 1,第 12 行字符串后的未闭合引号 ') GROUP BY WONum ) WC ON WO.WONum = WC.WONum 第二个有效。 '。
  • 所以我修复了第一个查询,第二个查询是您的计数表(动态创建 - 无需创建任何对象)
  • 第一个查询在您修复它后工作.. 列出了很多记录... 12538210 条记录.. ------------ 日期范围是 01-Jan- 2016年至今;希望我能在需要时更改日期范围...
  • 您预计有多少工单? (到目前为止,这是列出的每个工单)SELECT COUNT(*), COUNT(DISTINCT WONum) FROM WorkOrder 返回什么?请记住,这不是我们只是设置它的最终解决方案。所以我们只需要 1000 条左右的日期记录。我会更新答案。
  • 是否有任何工作订单在 2016 年 1 月 1 日之前关闭,如果是,您想完全排除它们吗?
猜你喜欢
  • 2019-07-11
  • 2022-06-22
  • 2019-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多