SQL Oracle SQL条件联接

SQL Oracle SQL条件联接,sql,oracle,Sql,Oracle,我正在研究一个资产管理系统的Oracle SQL查询。我的查询使用AMS设备表中的信息更新数据仓库。不幸的是,AMS有点垃圾,设备表中没有最后修改的日期,也没有任何方法可以通过审核获得 设备表有2000000条记录,所以我不想在办公时间更新整件事。相反,我想将其限制在与最近更新的工单关联的设备上。但我还需要在一夜之间更新整个表,以获取任何尚未附加到工单的新记录。我希望避免有两个导入,这样我就不会出现一个导入被更改而另一个没有更改的情况 我所追求的是一种方式,基于一天中的时间,我可以添加一个额外的

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

设备表有2000000条记录,所以我不想在办公时间更新整件事。相反,我想将其限制在与最近更新的工单关联的设备上。但我还需要在一夜之间更新整个表,以获取任何尚未附加到工单的新记录。我希望避免有两个导入,这样我就不会出现一个导入被更改而另一个没有更改的情况

我所追求的是一种方式,基于一天中的时间,我可以添加一个额外的加入

因此,在办公时间内:

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条件是有条件的,但是我没有发现任何地方连连接都是有条件的。这可能吗?

使用EXTRACTHOUR FROM CASTsysdate作为时间戳来确定一天中的时间

在下面的示例中,我确定工作时间为上午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 

使用IN子句比使用join更容易做到这一点,使用或允许应用几个条件之一。假设您希望在晚上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 
   )

我想你可以这样做:

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中提到了这一点:但我还需要在一夜之间更新整个表,以获取尚未附加到工单的任何新记录。您可以通过检查日期或检查work_orders表中是否存在新记录来获取新记录:

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

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 ) );

希望这有帮助。

我对这个问题的看法。我在WHERE子句中使用and EXISTS结构的OR语句的延迟求值。这样,所有条件都是WHERE子句的一部分

样本数据

获取所有适用的设备ID。 晚上9点之前,OR条件的第一部分失效,下一部分进行评估。晚上9点后,OR条件的第一部分有效,由于延迟评估,下一部分不再有效

实际解决方案


[]

我不认为在SELECT语句中可以在该位置使用该大小写。将其放入SQL developer中表示“否”不起作用SQL命令未正确结束于第3行第11列系统不喜欢HH24位,但改用EXTRACT起作用。谢谢很抱歉,用双引号代替单引号-现在应该可以正常工作了。系统不喜欢HH24位,但是用EXTRACT代替可以工作。谢谢
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 ) );
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' );
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 );