2个表中的子查询

时间:2015-05-06 05:38:43

标签: oracle join subquery

我有两张桌子:机器和工作。

表:机器

machine_no       downtime      location
A1-100-01           2             A1
A1-100              1.5           A1
A1-200              3             A1
CC3-100-01          0.5           CC3
CC3-100             1.5           CC3

表:工作

machine_no         date
A1-100-01         2/4/14                 
A1-100            2/14/14
A1-200            2/6/14
CC3-100-01        3/15/14
CC3-100           3/2/14

我希望输出如下:

machine_no        total_downtime                          month
  A1-100              3.5 (total of A1-100, A1-100-01)      02
  A1-200              3                                     02

选择位置A1时。

SELECT machine_no, SUM(downtime) as total_downtime
FROM ( 
  SELECT 
         SUBSTR(machine_no, 1,
             CASE WHEN INSTR(machine_no, '-', 1, 2) = 0 
                THEN LENGTH(machine_no) 
                ELSE INSTR(machine_no, '-', 1, 2)-1 
                END) as machine_no,
         downtime 
  FROM machine 
  WHERE location='A1'
) InnerQuery
GROUP BY machine_no

如何加入表格工作并显示月份?我使用的是Oracle。

谢谢。

2 个答案:

答案 0 :(得分:0)

您预期的查询结果中的month列语义不清楚。假设它是另一个聚合"键",那么您的查询将是

select
    regexp_substr(M.machine_no, '^[^-]+-[^-]+') as machine_no,
    sum(downtime) as total_downtime,
    to_char(W.date, 'mm') as month
from machine M
    join work W
        on W.machine_no = M.machine_no
group by
    regexp_substr(M.machine_no, '^[^-]+-[^-]+'),
    to_char(W.date, 'mm')
;

假设它是(某种程度上)聚合的值,让我们通过min()函数说,那么你的查询将是

select
    regexp_substr(M.machine_no, '^[^-]+-[^-]+') as machine_no,
    sum(downtime) as total_downtime,
    min(to_char(W.date, 'mm')) as month
from machine M
    join work W
        on W.machine_no = M.machine_no
group by
    regexp_substr(M.machine_no, '^[^-]+-[^-]+')
;

此外,这两个假设您的预期结果中的(total of A1-100, A1-100-01)只是您的注释,而不是结果的一部分。但如果没有,那么你的查询可能就像

那样
select
    regexp_substr(M.machine_no, '^[^-]+-[^-]+') as machine_no,
    sum(downtime)||
        case when count(1) > 1 then
            ' (total of '||
            listagg(M.machine_no)
                within group (order by M.machine_no)||
            ')'
        end
        as total_downtime,
    to_char(W.date, 'mm') as month
from machine M
    join work W
        on W.machine_no = M.machine_no
group by
    regexp_substr(M.machine_no, '^[^-]+-[^-]+'),
    to_char(W.date, 'mm')
;

即便如此,因为对machinework表格的(未说明的)属性做了一些假设,所以我会在这里停止我的回答。 : - )

答案 1 :(得分:0)

用户正则表达式获取machine_no和to_char的子字符串以获取月份

WITH machine(machine_no, downtime, location) as (
    select 'A1-100-01', 2, 'A1' from dual union all
    select 'A1-100', 1.5, 'A1' from dual union all
    select 'A1-200', 3, 'A1' from dual union all
    select 'CC3-100-01', 0.5, 'CC3' from dual union all
    select 'CC3-100', 1.5, 'CC3' from dual),
work(machine_no, ddate) as (
    select 'A1-100-01', to_date('2/4/14', 'mm/dd/yyyy') from dual union all                 
    select 'A1-100', to_date('2/14/14', 'mm/dd/yyyy') from dual union all
    select 'A1-200', to_date('2/6/14', 'mm/dd/yyyy') from dual union all
    select 'CC3-100-01', to_date('3/15/14', 'mm/dd/yyyy') from dual union all
    select 'CC3-100', to_date('3/2/14', 'mm/dd/yyyy') from dual)
--End of data preparation    
SELECT regexp_substr(m.machine_no, '^\w+-\w+') AS machine_no, 
       sum(m.downtime) downtime_sum, 
       to_char(w.ddate , 'MM') MONTH
  FROM WORK w
  JOIN machine m ON m.machine_no = w.machine_no
 WHERE m.location = 'A1'
 GROUP BY regexp_substr(m.machine_no, '^\w+-\w+'), 
       to_char(w.ddate , 'MM');

输出:

| MACHINE_NO | DOWNTIME_SUM | MONTH |
|------------|--------------|-------|
|     A1-200 |            3 |    02 |
|     A1-100 |          3.5 |    02 |