【问题标题】:What technique should I use to extract this data?我应该使用什么技术来提取这些数据?
【发布时间】:2014-01-31 01:20:23
【问题描述】:

我正在尝试填充此数据以构建按产品类型划分的每小时输出。基本上每条线上可以运行3类产品。它可以每小时更换 4 次,但有时一个产品会运行一整天。

Line  Product  Hour  ProductStopped           TimeStamp                HourCount
1     A        7     2014-01-28 07:56:30.000  2014-01-28 07:52:47.000  222
1     A        7     2014-01-28 07:56:30.000  2014-01-28 07:53:52.000  225
1     A        7     2014-01-28 07:56:30.000  2014-01-28 07:54:57.000  297
1     B        7     2014-01-28 08:05:20.000  2014-01-28 07:54:57.000  297
1     A        7     2014-01-28 07:56:30.000  2014-01-28 07:55:59.000  321
1     B        7     2014-01-28 08:05:20.000  2014-01-28 07:55:59.000  321
1     B        7     2014-01-28 08:05:20.000  2014-01-28 07:57:02.000  332
1     B        7     2014-01-28 08:05:20.000  2014-01-28 07:58:08.000  364
1     B        7     2014-01-28 08:05:20.000  2014-01-28 07:59:14.000  420
1     B        8     2014-01-28 08:05:20.000  2014-01-28 08:00:16.000  456
1     B        8     2014-01-28 08:05:20.000  2014-01-28 08:01:19.000  489
1     B        8     2014-01-28 08:05:20.000  2014-01-28 08:02:22.000  523
1     B        8     2014-01-28 08:05:20.000  2014-01-28 08:03:25.000  589
1     A        8     NULL                     2014-01-28 08:03:25.000  589
1     B        8     2014-01-28 08:05:20.000  2014-01-28 08:04:30.000  634
1     A        8     NULL                     2014-01-28 08:04:30.000  634
1     B        8     2014-01-28 08:05:20.000  2014-01-28 08:05:35.000  678
1     A        8     NULL                     2014-01-28 08:05:35.000  678
1     A        8     NULL                     2014-01-28 08:06:39.000  720
1     A        8     NULL                     2014-01-28 08:07:45.000  745

HourCount 是从班次开始(早上 7 点)开始生产的零件数量,并将计算到班次结束(晚上 7 点)。如果产品从 A 变为 B,HourCount 仍然继续,因为它与产品无关,而是与机器有关。我想知道每个产品每小时生产多少。 我希望这张表看起来像这样:

Line   Product   Hour   Quantity
1      A         7      321
1      B         7      78
1      C         7      0          (or without this row if is 0 for the product)
1      A         8      56
1      B         8      346
........
2      A         7      533
2      B         7      43
....

我添加了新列 ProductStopped,其中记录了产品停止输出时的日期和时间,不幸的是我无法添加何时开始,因为这将解决我的所有问题:) 我稍微修改了@OGHaza 解决方案,它给了我几乎正确的值,我现在遇到的问题是当 ProductStopped 为 NULL 时(仍在运行)。

WITH cte AS (
  SELECT t1.*
  ,CASE WHEN t1.Stop >
        (SELECT top 1 Stop
         FROM t t2
         WHERE t1.TimeStamp = t2.TimeStamp
           AND t1.LineID = t2.LineID
           AND t1.Hour = t2.Hour 
           AND t1.Product <> t2.Product
           AND t1.HourCount = t2.HourCount
         ORDER BY TimeStamp
         )
         OR t1.Stop IS NULL
    THEN 0
    ELSE 1
   END AS InProduction
FROM t t1
)

SELECT LineID
    ,Product
    ,Hour
    ,SUM(CASE WHEN PrevInProduction = 1 
          THEN HourCount - PrevCount
          ELSE 0
     END) AS Units
FROM (SELECT t1.*
        ,(SELECT top 1 InProduction
          FROM cte t2
          WHERE t2.TimeStamp < t1.TimeStamp
            AND t1.Product = t2.Product
            AND t1.LineID = t2.LineID
          ORDER BY TimeStamp DESC
         ) AS PrevInProduction
        ,(SELECT top 1 HourCount
          FROM cte t2
          WHERE t2.TimeStamp < t1.TimeStamp
            AND t1.Product = t2.Product
            AND t1.LineID = t2.LineID
          ORDER BY TimeStamp DESC
         ) AS PrevCount
  FROM cte t1
 ) t1
GROUP BY LineID, Hour, Product
ORDER BY LineID, Hour, Product

非常感谢

【问题讨论】:

  • 我无法弄清楚您数据的第 3-7 行发生了什么。第 2 行 = +3A,第 3 行 = +72A,然后呢?
  • 好的,机器可以同时运行两个产品,但是这个产品只有一个在输出。所以在第 4 行产品 B 已经开始但尚未输出。第 5 行产品 A 结束,第 6-7 行产品 B 开始输出。产品 B 的数据应从 6 开始计数(产品 B 应读取为 0)。
  • 2014-01-28 07:58:02.000 条目的计数为 332,2014-01-28 07:57:06.000 为 364?有可能还是那里有错字?
  • 另外,您想要的 Line 1 Product B Hour 7 输出中的 78 应该反映数据样本还是随机数?假设 389 是 Line 1 Hour 7 的最后一次计数,我希望它是 68。
  • @Andriy M,我已经更新了表格,因为它是一个错字。我还在表格顶部添加了更多数据。另一个表只是一个随机值。

标签: sql sql-server sql-server-2008-r2


【解决方案1】:

如果您可以针对不包含未输出产品行的数据进行报告,或者在 HourCount 不是增量的情况下更好,那么您的数据将是一大堆更容易使用。

首先,我选择构建一个计算每一行的 CTE,无论该行是否对应于正在输出的产品。

SELECT t1.*
  ,CASE WHEN t1.Product <> 
            (SELECT top 1 Product
             FROM t t2
             WHERE t2.TimeStamp < t1.TimeStamp
               AND t1.Line = t2.Line
             ORDER BY TimeStamp desc
                     ,CASE WHEN t1.Product = t2.Product
                           THEN 1
                           ELSE 0
                      END DESC
             ) 
        THEN 0
        ELSE 1
   END AS InProduction
FROM t t1

然后我得到每行之间HourCount 的差异,0如果产品没有在其前一行输出,则该值。然后我GROUP那些值。

SELECT Line
    ,Product
    ,Hour
    ,SUM(CASE WHEN PrevInProduction = 1 
              THEN HourCount - PrevCount
              ELSE 0
         END) AS Units
FROM (SELECT t1.*
            ,(SELECT top 1 InProduction
              FROM cte t2
              WHERE t2.TimeStamp < t1.TimeStamp
                AND t1.Product = t2.Product
                AND t1.Line = t2.Line
              ORDER BY TimeStamp DESC
             ) AS PrevInProduction
            ,(SELECT top 1 HourCount
              FROM cte t2
              WHERE t2.TimeStamp < t1.TimeStamp
                AND t1.Product = t2.Product
                AND t1.Line = t2.Line
              ORDER BY TimeStamp DESC
             ) AS PrevCount
      FROM cte t1
     ) t1
GROUP BY Line, Hour, Product
ORDER BY Line, Hour, Product

它看起来确实可以优化,但它给出了SQLFiddle上给定测试数据的预期结果

【讨论】:

  • 我已经尝试过了,但没有给出正确的结果。当我将此行 (1, 'A', 7, '2014-01-28 07:58:02.000', 332) 添加到第 6 行和第 7 行之间的 SQLFiddle 时,我会得到错误的结果。产品更改通常需要大约 5-10 行。除此之外,它运作良好。我会有一个剧本,并会尝试重新设计这个。谢谢
  • @Whistler,如果您添加该行,我不清楚您如何知道正在输出哪种产品
  • 好的,当您看到产品 A 和 B 具有相同的 HourCount 时,这意味着前一个正在运行的是当前输出(本例中为 A)。然后,如果只有 B 显示增加的 HourCount,则意味着 A 完成并且 B 开始输出。希望有意义
  • 我发现我可以在表格中添加产品停止输出的确切时间。不幸的是,没有存储开始输出的日期。这会有帮助吗?
  • 对不起,我为所提供的数据想出了一个解决方案,但我想不出如何进一步解决它。如果您能找到一种合适的方法来确定产品是否在 cte 中输出,那么第二个查询将完成剩下的工作。
【解决方案2】:

真的很难理解你想在这里做什么。但如果只是要查找每小时每行的产品数量,您可以这样做:

-- Uncomment the #1 sections if you want dates too
SELECT Line, Product, Hour, COUNT(*) AS ProductCountPerHour 
   --, CAST(TimeStamp as DATE) DateVal /* #1 */
FROM YourTable
GROUP BY Line, Product, Hour 
   --, CAST(TimeStamp as DATE) DateVal /* #1 */
ORDER BY -- DateVal ASC, /* #1 */
   Hour ASC

SELECT 和 GROUP BY 中的 Scratch Line,您将获得每小时所有产品线中所有产品的数量

【讨论】:

  • 对不起,我应该更具体一些。将在几分钟内更新问题。谢谢
  • COUNT(*) 只统计记录数,与商品数量无关。
  • 这就是为什么我说它很难理解。现在感谢编辑解释 HourCount 实际上是每台机器的 productCount,这是可行的。 :) 但我假设您在下面的回复会起作用,稍后会检查。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-27
  • 1970-01-01
  • 1970-01-01
  • 2010-09-19
  • 1970-01-01
  • 2010-09-29
  • 2020-11-22
相关资源
最近更新 更多