行分序重要的SQL分组......可能吗?

时间:2014-03-04 13:22:55

标签: sql oracle

你按照相同的东西分组......我可以按连续的事物分组吗?我有一台机器有一个工具,工具用于一些工作,然后它从机器上下来,我得到另一个工具,它运行,然后第一个工具回来。我想要三个记录,而不是两个,即使只有两个工具。

想象一下,您的数据如下所示:

Select
'1' as Machine,
'A' as Tool,
'ZZ' as Product,
sysdate as Start_date,
sysdate+(6/24) as End_Date
from dual
union all
Select
'1' as Machine,
'A' as Tool,
'QQ' as Product,
sysdate+(6/24) as Start_date,
sysdate+(12/24) as End_Date
from dual
union all
Select
'1' as Machine,
'B' as Tool,
'WW' as Product,
sysdate+(12/24) as Start_date,
sysdate+(18/24) as End_Date
from dual
UNION ALL
Select
'1' as Machine,
'A' as Tool,
'QQ' as Product,
sysdate+(18/24) as Start_date,
sysdate+1 as End_Date
from dual

并且您想编写一个导致此结果的SQL查询:

+---------------+------------+------------+
|     Machine   |    Tool    |   Run_time |
+---------------+------------+------------+
|     1         |    A       |     12 hrs |
|     1         |     B      |     6 hrs  |
|     1         |     A      |     6 hrs  |
+---------------+------------+------------+

不是这个:

+---------+------+----------+
| Machine | Tool | Run_time |
+---------+------+----------+
| 1       | A    | 18 hrs   |
| 1       | B    | 6 hrs    |
+---------+------+----------+

如果重要的话,这是一个Oracle数据库。

2 个答案:

答案 0 :(得分:1)

您可以使用“技巧”来执行此操作,该技巧使用row_number()

中的差异
select machine, tool, sum(end_date - start_date)*24 as run_time_hours
from (select t.*,
             (row_number() over (partition by machine order by start_date) -
              row_number() over (partition by machine, tool order by start_date)
             ) as grp
      from table t
     ) t
group by grp, machine, tool;

Here是一个SQL小提琴。

我会告诉你如何运作。您的样本足够小,您可以非常轻松地对行号进行计算。

答案 1 :(得分:0)

是的,您可以使用分析按连续元素进行分组。例如,您可以通过使用列上的运行总计来创建“分组”列,该列仅在存在间隙时获取值(在工具中切换):

SQL> SELECT machine, tool, SUM(time_hr)
  2    FROM (SELECT machine, tool, time_hr, start_date,
  3                 SUM(gap) OVER(PARTITION BY machine
  4                                   ORDER BY start_date) usage_group
  5             FROM (SELECT machine, tool, start_date,
  6                          (end_date - start_date) * 24 time_hr,
  7                           CASE
  8                              WHEN tool != LAG(tool)
  9                                              OVER(PARTITION BY machine
 10                                                       ORDER BY start_date)
 11                              THEN 1
 12                              ELSE
 13                               0
 14                           END gap
 15                      FROM DATA))
 16   GROUP BY machine, tool, usage_group
 17   ORDER BY MIN(start_date);

MACHINE TOOL SUM(TIME_HR)
------- ---- ------------
1       A              12
1       B               6
1       A               6