案例何时陈述日期

时间:2016-09-30 18:49:40

标签: sql oracle

我的情况,当陈述似乎不正确,我无法弄清楚出了什么问题。它为创建时间和更新时间记录提供了相同的日期。 这是我的数据的样子:

T1:

ID      create_time  
1      08/09/2016 07:30:20AM

T2:

ID   update_time  
1      
1   08/15/2016 09:41:46AM 

我期待以下内容:

ID  TimeStamp  
1   08/09/2016 07:30:20AM  
1   08/15/2016 09:41:46AM

但是我的代码返回2条记录的创建时间值。它看起来像这样:

ID  TimeStamp  
1   08/09/2016 07:30:20AM  
1   08/09/2016 07:30:20AM

select t1.id, t1.desc,
Case
WHEN t1.create_time IS NOT NULL
THEN t1.create_time
WHEN t2.update_time IS NOT NULL
THEN t2.update_time
END AS "TimeStamp"
from t1, t2
where t1.id=t2.id
AND ( t1.create_time BETWEEN TO_DATE ('01-AUG-2016 00:00:00',
                               'dd-mon-yyyy HH24:Mi:SS')
               AND TO_DATE ('31-AUG-2016 23:59:59',
                            'dd-mon-yyyy HH24:Mi:SS')
   OR (  t2.update_time
               BETWEEN TO_DATE ('01-AUG-2016 00:00:00',
                                'dd-mon-yyyy HH24:Mi:SS')
               AND TO_DATE ('31-AUG-2016 23:59:59',
                            'dd-mon-yyyy HH24:Mi:SS')
            )
        )

我还需要在单独的列中将基于创建/更新时间的每条记录标记为New / Update。我正在使用案例,如下所示:

CASE 
WHEN (t1.create_time IS NOT NULL AND t2.update_time IS NULL)
THEN 'New'
WHEN t2.update_time IS NOT NULL
THEN 'Update'
END AS "Type"

但这似乎带来重复如下:
ID TimeStamp类型
1 08/09/2016新的 1 08/09/2016更新
1 08/15/2016新的 1 08/15/2016更新

2 个答案:

答案 0 :(得分:1)

这样做你想要的吗?

select t1.id, t1.desc,
       coalesce(t2.update_time, t1.create_time) as "TimeStamp"
from t1 left join
     t2
     on t1.id = t2.id and
        t2.update_time >= date '2016-08-25' and 
        t2.update_time < date '2016-09-01'
where (t1.create_time >= date '2016-08-25' and
       t1.create_time < date '2016-09-01'
      ) or
      t2.update_time is not null;

编辑:

您似乎想要在指定时间段内具有更新或创建的任何记录的更新和创建时间列表。我认为这看起来像:

with ids as (
      select t1.id, t1.desc, t1.create_time
      from t1 join
           t2
           on t1.id = t2.id
      where (t1.create_time >= date '2016-08-25' and
             t1.create_time < date '2016-09-01'
            ) t or
            (t2.update_time >= date '2016-08-25' and 
             t2.update_time < date '2016-09-01'
            )
     )
select ids.*
from ids
union all
select ids.id, ids.desc, t2.update_time
from ids join
     t2
     on t2.id = ids.id
where t2.update_time is not null;  -- I'm not sure if the range should also be checked here.

注意:

  • 从不FROM子句中使用逗号。 始终使用带有JOIN子句的显式ON
  • 对即使是Oracle弃用的古老的外连接语法说不。使用显式外连接。
  • Oracle支持date关键字,因此您可以使用ISO标准格式输入日期。

答案 1 :(得分:0)

你做一个外连接,所以你会得到两行(所有id都是1)。在第二个中,t2.update_time为NULL。

&#xA;&#xA;

您的查询,您编写它的方式,首先测试t1.create_time为非null。对于外连接中的两行,这是正确的。因此,只评估第一个“WHEN ...... THEN”。

&#xA;&#xA;

请解释所需输出的逻辑;只显示它,并显示一个不符合您要求的查询,并不构成您的要求的“完整规范”。

&#xA;&#xA;

EDIT :对本答案的评论中的OP陈述了他需要得到的是create_time以及所有非null update_time值。

&#xA;&#xA;

这很容易,不会需要连接,它需要一个UNION(或UNION ALL)。在示例数据中,所有行都具有相同的ID;如果在现实生活中有更多的ID,可以使用WHERE子句选择一个。

&#xA;&#xA;
 选择id,create_time作为来自t1&#xA的时间戳;联合所有&# xA;从t2选择id,update_time,其中up​​date_time不为null;&#xA;  
&#xA;&#xA;

(可能添加 ORDER BY id,timestamp - 如果需要)

&#xA;&#xA;

OP:如果这不是理想的结果,请解释它与您需要的不同。

&#xA; &#xA;

编辑编号2 :OP增加了要求 - 还需要一个类型标记。

&#xA;&#xA;
 选择id,create_time作为时间戳,'New'作为来自t1&#xA的类型; union all&#xA; select id,update_time,'update'来自t2,其中up​​date_time不为null;&#xA;  < / PRE>&#XA;