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