我应该使用什么技术来提取这些数据?

时间:2014-01-28 11:01:37

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

我正在尝试填充此数据以构建按产品类型划分的每小时输出。基本上每行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

非常感谢

2 个答案:

答案 0 :(得分: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 :(得分:0)

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

-- 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,您将获得每小时所有产品的数量