我制作了一个程序来显示特定日期特定时间内最高和最低的热门项目。该过程适用于没有错误或异常,并且每个东西都可以运行。如您所见,查询重复两次以显示Items上的第一条记录,但唯一的区别在于Order(ASC和DESC)!有什么办法可以减少代码的数量吗?如何在一个查询中显示最高和最低项目而不是两个?我只想让代码整洁易读。任何帮助将非常感激。
CREATE OR REPLACE PROCEDURE highest_lowest(param IN DATE)
AS
v_pno_low NUMBER(5);
v_pno_high NUMBER(5);
BEGIN
SELECT item_no INTO v_pno_low
FROM (
SELECT
items.item_no,
sum(items.quantity) AS total,
to_char(prodcution_d, 'dd-mm-yyyy') AS pro_date
FROM items
JOIN parts ON parts.serial_no = items.serial_no
GROUP BY item_no, to_char(prodcution_d, 'dd-mm-yyyy')
ORDER BY sum(items.quantity) ASC)
WHERE rownum = 1
AND pro_date = to_char(param_date, 'mm-yyyy');
dbms_output.put_line('LOWEST ITEM: ' || v_pno_low);
SELECT item_no INTO v_pno_low
FROM (
SELECT
items.item_no,
sum(items.quantity) AS total,
TO_CHAR(prodcution_d, 'dd-mm-yyyy') AS pro_date
FROM items
JOIN parts ON parts.serial_no = items.serial_no
GROUP BY item_no, to_char(prodcution_d, 'dd-mm-yyyy')
ORDER BY SUM(items.quantity) DESC)
WHERE rownum = 1
AND pro_date = to_char(param_date, 'mm-yyyy');
dbms_output.put_line('HIGHEST POPULAR ITEM: ' || v_pno_high);
END;
/
答案 0 :(得分:1)
使用FIRST
和LAST
函数在一个查询中获取最大值和最小值:
--Step 2: The SERIAL_NO for the smallest and largest quantity per day.
select
min(serial_no) keep (dense_rank first order by quantity_sum) low_serial_no,
min(serial_no) keep (dense_rank last order by quantity_sum) high_serial_no
into v_pno_low, v_pno_high
from
(
--Step 1: Sum of quantity, per day, for the specified month.
select
items.serial_no,
trunc(production_date, 'day') the_date,
sum(quantity) quantity_sum
from items
join parts
on items.serial_no = parts.serial_no
where trunc(production_date, 'month') = trunc(param_date, 'month')
group by items.serial_no, trunc(production_date, 'day')
);
KEEP
语法起初有点令人困惑。外部查询获取SERIAL_NO的最小值,但仅限于第一个(最低)QUANTITY_SUM和最后一个(最高)QUANTITY_SUM的行。
该查询还使用TRUNC
代替TO_CHAR
。通常最好将日期保留为日期并避免任何转换功能。