Oracle SQL Count在不重复前几天的记录的情况下进行分组

时间:2017-11-15 10:39:36

标签: sql oracle count sum grouping

我需要计算白天不同的WO组,但不计算前几天已经过的WO。并且按天分类LABOR列分组。

示例:

DAY   WO     LABOR
6   379157    3
9   379157    5
10  379404    8
10  379362    8
19  386118    10
24  386547    2
25  388711    8
25  386547    5
30  386547    1

结果

DAY   WO    LABOR
6      1    3
9      0    5
10     2    16
19     1    10
24     1    2
25     1    13
30     0    1

非常感谢你的帮助

5 个答案:

答案 0 :(得分:3)

这是一个使用row_number的解决方案(因为我们只想计算每天所有日子的第一个实例):

WITH your_table AS (SELECT 6 DAY, 379157 wo, 3 labor FROM dual UNION ALL
                    SELECT 9 DAY, 379157 wo, 5 labor FROM dual UNION ALL
                    SELECT 10 DAY, 379404 wo, 8 labor FROM dual UNION ALL
                    SELECT 10 DAY, 379362 wo, 8 labor FROM dual UNION ALL
                    SELECT 19 DAY, 386118 wo, 10 labor FROM dual UNION ALL
                    SELECT 24 DAY, 386547 wo, 2 labor FROM dual UNION ALL
                    SELECT 25 DAY, 388711 wo, 8 labor FROM dual UNION ALL
                    SELECT 25 DAY, 386547 wo, 5 labor FROM dual UNION ALL
                    SELECT 30 DAY, 386547 wo, 1 labor FROM dual)
-- end of mimicking data in "your_table" - see the main SQL below:
SELECT DAY,
       SUM(CASE WHEN rn = 1 THEN 1 ELSE 0 END) wo,
       SUM(labor) labor
FROM   (SELECT DAY,
               wo,
               labor,
               row_number() OVER (PARTITION BY wo ORDER BY DAY) rn
        FROM   your_table)
GROUP BY DAY
ORDER BY DAY;

       DAY         WO      LABOR
---------- ---------- ----------
         6          1          3
         9          0          5
        10          2         16
        19          1         10
        24          1          2
        25          1         13
        30          0          1

答案 1 :(得分:2)

我认为你应该GROUP BY WO,并将作为一个子查询的WO发生的MIN日取回。前者基本上是对您的第一个要求的重新陈述。它不是看WO而是试图排除前几天出现的WO,它可以被认为是“WO应该在任何一天第一次出现时才真正有效== WO和第一天的价值(它出现在“

然后,此数据集应与另一个数据集合并,该数据集是所有日期的人工总和。

因为子查询中会有更多的天数来累计劳动力(源中每天都会有一天),但不一定要在选择最小日的查询中出现多少天每个wo,具有更多天数的查询应该作为左连接的左侧

SELECT
  labors.day, count(wo), min(sumlabor)
FROM
(
  SELECT day, sum(labor) as sumlabor FROM t GROUP BY day
) labors
LEFT OUTER JOIN
(
  SELECT wo, min(day) as day FROM t GROUP BY wo
) wos
ON 
  wos.day = labors.day

GROUP BY 
  labors.day

希望解释我如何看待你的问题,以及我如何从中编写一个查询,将有助于你思考未来的类似问题 - 有时候更容易将逻辑放在头上/状态另一种方式,在从中写入查询之前

答案 2 :(得分:2)

以下是LAG的查询。我们的想法是看看是否有一个旧的条目,只有在没有的情况下才计算它。

select day, count(case when prev_day is null then 1 end) as wos, sum(labor) as labor
from
(
  select mytable.*, lag(day) over (partition by wo order by day) as prev_day
  from mytable
) 
group by day
order by day;

(如果每天可以有多个条目,您必须稍微改变查询。一种方法是:partition by wo order by day, rowid。)

答案 3 :(得分:0)

试试这个,如果有效

select COUNT(tbl1.wo), sum(tbl1.labor) FROM Table_Name tbl1
where tbl1.wo not in (SELECT tbl2.wo from Table_Name tbl2 WHERE tbl2.day < tbl1.day)
group by tbl1.day

答案 4 :(得分:0)

这适用于给定的数据集:

ZZ (XYZ)