我是PL / SQL和Oracle SQL查询的新手。
我想要实现的目标是什么? 获取从今天起最后100天发货的所有包装盒(sysdate - 100),标签为“600”。在这些框中,我需要隔离具有更新标签“50”和“51”的框。
逻辑:
1.获取最后100个标签为“600”的所有包装盒。此外,获取标签“600”在过去100天内发货的数量。 (例如,今天是09/06,获取所有在05/29发货的箱子)
2.获取具有更新标签的所有框的计数。 E.G,06/01年,其中一个箱子从“600”移开 - > “50”,我需要考虑这个盒子。
我正在尝试为这个用例编写一个PL / SQL,这是迄今为止我已经达到的目标。
VARIABLE box_id CHAR(50);
BEGIN
FOR box_id IN (SELECT
box_id, box_lable
FROM
my.box_table
WHERE box_lable = '600'
AND trunc(boxed_date) = trunc(SYSDATE - 100)
) LOOP
select count(*), box_lable
from my.shipping_info si
where box_id = si.box_id
and box_lable in ( '51', '50')
group by box_lable
--COde to print the count of box_label = 600; count of box_label = 51; count of box_label = 50 .
END LOOP;
END;
上面的代码在SQL Developer中引发了错误。我在Oracle 11g和Oracle 12c上运行它。 只要解决方案适用于Oracle,我就可以灵活地使用任何方法(不一定是PL / SQL)。
您能否告诉我运行此代码段需要进行的更改?
答案 0 :(得分:1)
使用带有子查询的纯SQL而不是PL / SQL循环:
select box_lable, count(*)
from my.shipping_info si
where box_id IN (
SELECT box_id
FROM my.box_table
WHERE box_lable = '600'
AND trunc(boxed_date) = trunc(SYSDATE - 100)
)
and box_lable in ( '51', '50')
group by box_lable
还要考虑重写这个条件:
AND trunc(boxed_date) = trunc(SYSDATE - 100)
进入这一个:
AND boxed_date >= trunc(SYSDATE - 100)
AND boxed_date < trunc(SYSDATE - 99 )
这可能看起来很冗长,但有助于优化选择更好的执行计划,特别是允许在boxed_date
上使用索引(如果它存在)(函数trunc(boxed_date)
阻止optiomizer使用该索引)。