Oracle / SQL - 返回父记录和子记录

时间:2016-05-03 17:42:46

标签: sql oracle

我有一个问题,如何显示父母和孩子: 这是我的例子: T1是T2的父母。

ID     create datetime(mm/dd/yyyy hh:mm:ss)
1      17-Apr-2016
2      18-Apr-2016
3      13-Apr-2016
4      15-Apr-2016
5      20-Apr-2016
6      19-Apr-2016

ID(FK) seq      create datetime(mm/dd/yyyy hh:mm:ss)
1      6546       20-Apr-2016 
1      5457       19-Apr-2016 
1      4245       18-Apr-2016
1      0
2      5567       19-Apr-2016 
2      0
3      2034       15-Apr-2016 
3      1987       14-Apr-2016 
3      1902       14-Apr-2016 
3      1249       13-Apr-2016 
3      0
4      2209       15-Apr-2016 
4      2456       16-Apr-2016 
4      3578       17-Apr-2016 
4      3467       17-Apr-2016 
4      4645       18-Apr-2016 
4      5357       19-Apr-2016 
4      0
5      0
6      0

T2是T1的子节点,A和B是我想根据我的条件显示的文本值,这不是来自db。我的条件是:

  • 如果Id在T2 / Seq = 0中没有创建时间,则将ID列为“A”。例如:5,6会 是A
  • 如果Id在T2中有有效的seq /创建时间:     。然后,获取T2中的最大创建时间
  • 列出两行 - T1为'A',T2为'B'

理想情况下,我的输出是:

Id   createtime   Type
 1   17-Apr-2016   A
 1   20-Apr-2016   B
 2   18-Apr-2016   A
 2   19-Apr-2016   B
 3   13-Apr-2016   A
 3   15-Apr-2016   B
 4   15-Apr-2016   A
 4   15-Apr-2016   B
 5   20-Apr-2016   A
 6   19-Apr-2016   A

编辑:我还必须添加日期/时间过滤器 T1.createatetime在to_date(2016年4月1日)和to_date(2016年4月30日)之间 要么 在to_date(2016年4月1日至2016年)和to_date(2016年4月30日)之间的T2.createdate时间

3 个答案:

答案 0 :(得分:0)

我认为工会应该这样做:

WITH T1 as(
select 1 ID,      '17-Apr-2016' as crte from dual union all
select 2 ID,      '18-Apr-2016' as crte from dual union all
select 3 ID,      '13-Apr-2016' as crte from dual union all
select 4 ID,      '15-Apr-2016' as crte from dual union all
select 5 ID,      '20-Apr-2016' as crte from dual union all
select 6 ID,      '19-Apr-2016' as crte from dual
)
,
T2 as(
select 1 ID,     6546 SEQ,      '20-Apr-2016' as crte from dual union all
select 1 ID,     5457 SEQ,      '19-Apr-2016' as crte from dual union all
select 1 ID,     4245 SEQ,      '18-Apr-2016' as crte from dual union all
select 1 ID,     0 SEQ,         NULL as crte from dual union all
select 2 ID,     5567 SEQ,      '19-Apr-2016' as crte from dual union all
select 2 ID,     0 SEQ,         NULL as crte from dual union all
select 3 ID,     2034 SEQ,      '15-Apr-2016' as crte from dual union all
select 3 ID,     1987 SEQ,      '14-Apr-2016' as crte from dual union all
select 3 ID,     1902 SEQ,      '14-Apr-2016' as crte from dual union all
select 3 ID,     1249 SEQ,      '13-Apr-2016' as crte from dual union all
select 3 ID,     0 SEQ,         NULL as crte from dual union all
select 4 ID,     2209 SEQ,      '15-Apr-2016' as crte from dual union all
select 4 ID,     2456 SEQ,      '16-Apr-2016' as crte from dual union all
select 4 ID,     3578 SEQ,      '17-Apr-2016' as crte from dual union all
select 4 ID,     3467 SEQ,      '17-Apr-2016' as crte from dual union all
select 4 ID,     4645 SEQ,      '18-Apr-2016' as crte from dual union all
select 4 ID,     5357 SEQ,      '19-Apr-2016' as crte from dual union all
select 4 ID,     0 SEQ,         NULL as crte from dual union all
select 5 ID,     0 SEQ,         NULL as crte from dual union all
select 6 ID,     0 SEQ,         NULL as crte from dual
)

select ID, crte, 'A' Type from T1 where crte between to_date('01-Apr-2016') and to_date('30-Apr-2016')
union 
select ID, max(crte), 'B' Type from T2 where seq <> 0 and crte between to_date('01-Apr-2016') and to_date('30-Apr-2016')  group by ID;

输出:

        ID CRTE        TYPE
---------- ----------- ----
         1 17-Apr-2016 A    
         1 20-Apr-2016 B    
         2 18-Apr-2016 A    
         2 19-Apr-2016 B    
         3 13-Apr-2016 A    
         3 15-Apr-2016 B    
         4 15-Apr-2016 A    
         4 19-Apr-2016 B    
         5 20-Apr-2016 A    
         6 19-Apr-2016 A    

答案 1 :(得分:0)

这样的事情......请注意,我更改了输入数据,以便涵盖所有可能的组合(我认为)。

with t1 (id, create_datetime) as 
         ( select 1, date '2016-04-17' from dual union all
           select 2, date '2016-04-18' from dual union all
           select 3, date '2016-04-10' from dual
         ),
     t2 (id, seq, create_datetime) as
         (
           select 1, 6546, date '2016-04-20' from dual union all
           select 1, 5457, date '2016-04-19' from dual union all
           select 1, 4245, date '2016-04-18' from dual union all
           select 1, 0   , null              from dual union all
           select 2, 5567, date '2016-04-19' from dual union all
           select 2, 4003, date '2016-04-21' from dual union all
           select 3, 0   , null              from dual
         )
select t1.id, t1.create_datetime, 'A' as type
   from t1 join t2 on t1.id = t2.id 
   where t2.seq = 0
   and t1.create_datetime >= date '2016-04-01'
   and t1.create_datetime <  date '2016-05-01'
union all
select id, max(create_datetime), 'B'
   from t2
   where create_datetime >= date '2016-04-01'
   and   create_datetime <  date '2016-05-01'
   group by id
order by id, type;

输出(使用WITH子句中定义的t1和t2中的数据):

        ID CREATE_DATE TYPE
---------- ----------- ----
         1 17-Apr-2016 A
         1 20-Apr-2016 B
         2 21-Apr-2016 B
         3 10-Apr-2016 A

答案 2 :(得分:0)

您可以在没有联合的情况下执行此操作,并且在每个表上仅使用一次表扫描:

Oracle安装程序

CREATE TABLE T1 ( ID, CRTE ) AS
select 1, DATE '2016-04-17' FROM DUAL UNION ALL
select 2, DATE '2016-04-18' FROM DUAL UNION ALL
select 3, DATE '2016-04-13' FROM DUAL UNION ALL
select 4, DATE '2016-04-15' FROM DUAL UNION ALL
select 5, DATE '2016-04-20' FROM DUAL UNION ALL
select 6, DATE '2016-04-19' FROM DUAL;

CREATE TABLE T2 ( ID, SEQ, CRTE ) AS
select 1, 6546, DATE '2016-04-20' FROM DUAL UNION ALL
select 1, 5457, DATE '2016-04-19' FROM DUAL UNION ALL
select 1, 4245, DATE '2016-04-18' FROM DUAL UNION ALL
select 1, 0,    NULL              FROM DUAL UNION ALL
select 2, 5567, DATE '2016-04-19' FROM DUAL UNION ALL
select 2, 0,    NULL              FROM DUAL UNION ALL
select 3, 2034, DATE '2016-04-15' FROM DUAL UNION ALL
select 3, 1987, DATE '2016-04-14' FROM DUAL UNION ALL
select 3, 1902, DATE '2016-04-14' FROM DUAL UNION ALL
select 3, 1249, DATE '2016-04-13' FROM DUAL UNION ALL
select 3, 0,    NULL              FROM DUAL UNION ALL
select 4, 2209, DATE '2016-04-15' FROM DUAL UNION ALL
select 4, 2456, DATE '2016-04-16' FROM DUAL UNION ALL
select 4, 3578, DATE '2016-04-17' FROM DUAL UNION ALL
select 4, 3467, DATE '2016-04-17' FROM DUAL UNION ALL
select 4, 4645, DATE '2016-04-18' FROM DUAL UNION ALL
select 4, 5357, DATE '2016-04-19' FROM DUAL UNION ALL
select 4, 0,    NULL              FROM DUAL UNION ALL
select 5, 0,    NULL              FROM DUAL UNION ALL
select 6, 0,    NULL              FROM DUAL;

<强>查询

SELECT T1.id,
       COALESCE( T2.CRTE, T1.CRTE ) AS CRTE,
       CASE SEQ WHEN 0 THEN 'A' ELSE 'B' END AS Type
FROM   T1
       INNER JOIN
       ( SELECT t.*,
                CASE SEQ WHEN 0 THEN 1
                     ELSE ROW_NUMBER() OVER ( PARTITION BY ID
                                              ORDER BY CRTE DESC
                                              NULLS LAST )
                  END AS RN
         FROM   T2 t ) T2
       ON ( t1.ID = t2.ID AND t2.RN = 1 )
ORDER BY id, type;

<强>输出

        ID CRTE                TYPE
---------- ------------------- ----
         1 2016-04-17 00:00:00 A    
         1 2016-04-20 00:00:00 B    
         2 2016-04-18 00:00:00 A    
         2 2016-04-19 00:00:00 B    
         3 2016-04-13 00:00:00 A    
         3 2016-04-15 00:00:00 B    
         4 2016-04-15 00:00:00 A    
         4 2016-04-19 00:00:00 B    
         5 2016-04-20 00:00:00 A    
         6 2016-04-19 00:00:00 A

查询2 - 使用过滤器

SELECT T1.id,
       COALESCE( T2.create_datetime, T1.create_datetime ) AS create_datetime,
       CASE SEQ WHEN 0 THEN 'A' ELSE 'B' END AS Type
FROM   T1
       INNER JOIN
       ( SELECT T2.*,
                CASE SEQ WHEN 0 THEN 1
                     ELSE ROW_NUMBER() OVER ( PARTITION BY ID
                                              ORDER BY create_datetime DESC
                                              NULLS LAST )
                  END AS RN
         FROM   T2
         WHERE  create_datetime IS NULL
         OR     create_datetime BETWEEN DATE '2016-04-01'AND DATE '2016-04-30'
       ) T2
       ON ( t1.ID = t2.ID AND t2.RN = 1 )
WHERE  T1.create_datetime BETWEEN DATE '2016-04-01'AND DATE '2016-04-30'
ORDER BY id, type;

<强>输出

        ID CREATE_DATETIME     TYPE
---------- ------------------- ----
         1 2016-04-17 00:00:00 A    
         1 2016-04-20 00:00:00 B    
         2 2016-04-18 00:00:00 A    
         2 2016-04-19 00:00:00 B    
         3 2016-04-13 00:00:00 A    
         3 2016-04-15 00:00:00 B    
         4 2016-04-15 00:00:00 A    
         4 2016-04-19 00:00:00 B    
         5 2016-04-20 00:00:00 A    
         6 2016-04-19 00:00:00 A