oracle 如何基于不同where子句从表中选择多个列

dluptydi  于 2023-04-29  发布在  Oracle
关注(0)|答案(4)|浏览(172)

我想把这4个查询合并成一个查询:

select SUM(AMOUNT) as TOTAL_AMOUNT
from PAYMENT;
select SUM(AMOUNT) as NOT_SETTLED_AMOUNT
from PAYMENT
where STATE = 0;
select SUM(AMOUNT) as SETTLED_AMOUNT
from PAYMENT
where STATE = 1;
SELECT CREATION_DATE
        FROM PAYMENT
        WHERE PAYMENT_ID = (SELECT max(PAYMENT_ID) from PAYMENT)) as LATEST_PAYMENT_DATE;
SELECT MAX(ID) FROM INQUIRY
swvgeqrz

swvgeqrz1#

您可以使用条件聚合在一次表扫描中执行所有4个计算。关于最新付款id的创建日期,我们可以使用Oracle's keep syntax

select
    sum(amount) as total_amount,
    sum(case when state = 0 then amount else 0 end) as not_settled_amount,
    sum(case when state = 1 then amount else 0 end) as settled_amount,
    max(creation_date) keep(dense_rank last order by payment_id) as latest_payment_date
from payment

注意,这比使用子查询和/或联合的其他方法更有效。

fivyi3re

fivyi3re2#

一个选择是UNION它们。
添加另一列,说明什么是什么。
由于所有UNIONed查询必须具有相同的列数和相同的数据类型,并且由于最后一个查询返回date值(而其余所有查询都返回数字),因此将它们全部转换为带有to_char的字符串:

SELECT 'total amount' what, TO_CHAR (SUM (amount)) AS amount FROM payment
UNION ALL
SELECT 'not settled amount', TO_CHAR (SUM (amount))
  FROM payment
 WHERE state = 0
UNION ALL
SELECT 'settled amount', TO_CHAR (SUM (amount))
  FROM payment
 WHERE state = 1
UNION ALL
SELECT 'creation date', TO_CHAR (creation_date, 'dd.mm.yyyy')
  FROM payment
 WHERE payment_id = (SELECT MAX (payment_id) FROM payment)
UNION ALL
SELECT 'max ID', TO_CHAR (MAX (id)) FROM inquiry
ctzwtxfj

ctzwtxfj3#

对于前3个最适合你的是ROLLUP和CASE:

SELECT
    CASE state 
        WHEN 0 THEN 'NOT_SETTLED_AMOUNT'
        WHEN 1 THEN 'SETTLED_AMOUNT'
        ELSE 'TOTAL_AMOUNT'
    END
    , SUM(AMOUNT)
FROM 
    PAYMENT
GROUP BY ROLLUP (state);

对于创建日期,只需使用UNION ALL,如:Littlefoot说

yhxst69z

yhxst69z4#

可以在SUM中使用条件。

WITH totals AS
(
    SELECT
        SUM(AMOUNT) AS TOTAL_AMOUNT,
        SUM(CASE WHEN STATE = 0 THEN AMOUNT END) AS NOT_SETTLED_AMOUNT,
        SUM(CASE WHEN STATE = 1 THEN AMOUNT END) AS SETTLED_AMOUNT,
        MAX(ID) AS MAX_ID
    FROM PAYMENT
)
SELECT 
    t.TOTAL_AMOUNT,
    t.NOT_SETTLED_AMOUNT,
    t.SETTLED_AMOUNT,
    p.CREATION_DATE AS LATEST_PAYMENT_DATE 
FROM totals t LEFT OUTER JOIN PAYMENT p ON t.MAX_ID = p.ID;

如果您可以将最大CREATION_DATE作为最后一个付款日期,而不是查看最后一个ID的CREATION_DATE,那么查询将变得更简单:

SELECT
    SUM(AMOUNT) AS TOTAL_AMOUNT,
    SUM(CASE WHEN STATE = 0 THEN AMOUNT END) AS NOT_SETTLED_AMOUNT,
    SUM(CASE WHEN STATE = 1 THEN AMOUNT END) AS SETTLED_AMOUNT,
    MAX(CREATION_DATE) AS LATEST_PAYMENT_DATE
FROM PAYMENT;

相关问题