SQL Oracle SQL条件连接

时间:2018-05-01 13:31:09

标签: sql oracle

我正在研究资产管理系统的Oracle SQL查询。我的查询使用AMS设备表中的信息更新数据仓库。不幸的是,AMS有点垃圾,而且Equipment表中没有包含最后修改日期,也没有任何方法可以使用审计。

设备表有2,000,000条记录,所以我不想在办公时间内更新整件事。相反,我想将其限制为最近更新的与工作订单相关联的设备。但我还需要在一夜之间更新整个表格,以获取尚未附加到工作订单的任何新记录。我想避免有两个导入,所以我不会遇到一个导入被改变而另一个没有改变的情况。

我所追求的是一种方式,根据一天中的时间,我可以添加额外的连接。

所以在办公时间内会是:

SELECT
*
FROM
Equipment
INNER JOIN
  ( SELECT DISTINCT Equipment_ID FROM Work_Orders
    WHERE Work_Orders.Last_Update > SYSDATE - 2 
) WO
ON
Equipment.Equipment_ID = WO.Equipment_ID

但是在晚上9点之后它会是

 SELECT
 *
 FROM
 Equipment

我已经在其他地方看到了使用连接的示例,其中ON条件是有条件的,但是我没有找到任何地方甚至连接都是有条件的。这甚至可能吗?

4 个答案:

答案 0 :(得分:2)

使用IN子句而不是连接更容易,使用OR允许应用多个条件之一。让我们说你想要选择所有设备"选项在晚上9点到凌晨3点之间启用。你可以这样做:

SELECT
*
FROM
Equipment
WHERE TO_CHAR( SYSDATE, 'HH24' ) > '21'
   OR TO_CHAR( SYSDATE, 'HH24' ) < '03'
   OR Equipment_ID IN (
         SELECT DISTINCT Work_Orders.Equipment_ID FROM Work_Orders
         WHERE Work_Orders.Last_Update > SYSDATE - 2 
   )

答案 1 :(得分:2)

我认为你可以这样做:

SELECT * FROM equipment e
 WHERE EXISTS ( SELECT 1 FROM work_orders wo
                 WHERE wo.equipment_id = e.equipment_id
                   AND wo.last_update > SYSDATE-2 )
    OR TO_CHAR(SYSDATE, 'HH24') BETWEEN '09' and '17'; -- Assuming work hours are 9:00 am to 5:00 pm

现在你在OP中提到这一点:&#34;但是我还需要在一夜之间更新整个表格以获取尚未附加到工作订单的任何新记录。&#34;您可以通过检查日期或检查work_orders表中是否存在来获取新记录:

SELECT * FROM equipment e
 WHERE NOT EXISTS ( SELECT 1 FROM work_orders wo
                     WHERE wo.equipment_id = e.equipment_id );

将两个查询放在一起,我们可能会得到如下内容:

SELECT * FROM equipment e
 WHERE EXISTS ( SELECT 1 FROM work_orders wo
                 WHERE wo.equipment_id = e.equipment_id
                   AND wo.last_update > SYSDATE-2 )
    OR ( TO_CHAR(SYSDATE, 'HH24') BETWEEN '09' and '17'
     AND NOT EXISTS ( SELECT 1 FROM work_orders wo
                       WHERE wo.equipment_id = e.equipment_id ) );

希望这有帮助。

答案 2 :(得分:1)

我对这个问题的看法。我正在使用和EXISTS构造在WHERE子句中使用OR语句的惰性求值。这样所有条件都是WHERE子句的一部分。

示例数据

create table Equipment
(
  Id varchar(3)
);

insert into Equipment values ( 'E01' );
insert into Equipment values ( 'E02' );

create table Orders
(
  Num varchar(5),
  LastModified date,
  EquipmentId varchar(3)
);

insert into Orders values ( 'OR001', SYSTIMESTAMP-4, 'E01' );
insert into Orders values ( 'OR002', SYSTIMESTAMP-3, 'E02' );
insert into Orders values ( 'OR003', SYSTIMESTAMP, 'E01' );
insert into Orders values ( 'OR004', SYSTIMESTAMP, 'E01' );

获取所有适用的设备ID。 在晚上9点之前,OR条件的第一部分失败,并评估下一部分。在晚上9点之后,OR条件的第一部分是有效的(由于懒惰的评估,下一部分不再被验证)。

实际解决方案

select distinct Id
from Equipment
where extract(HOUR from SYSTIMESTAMP) > 21 -- after 9pm do not evaluate the next part of OR condition
   or exists (  select 'x'
                from Orders
                where EquipmentId = Id
                  and LASTMODIFIED > SYSDATE-2 );

[SQL Fiddle]

答案 3 :(得分:0)

使用EXTRACT(HOUR FROM CAST(sysdate AS timestamp))确定一天中的时间。

我决定&#34;工作时间&#34;在下面的例子中是上午9点到下午5点。

SELECT * 
FROM CASE 
     WHEN EXTRACT(HOUR FROM CAST(sysdate AS timestamp)) BETWEEN 9 AND 17
     THEN (SELECT *
           FROM Equipment e
           INNER JOIN (SELECT DISTINCT Equipment_ID 
                       FROM Work_Orders w
                       WHERE w.Last_Update > SYSDATE - 2) WO
           ON e.Equipment_ID = WO.Equipment_ID)
    ELSE (SELECT * FROM Equipment)
    END