这个倍数self-JOIN可以优化吗?

can this multiple self-JOIN be optimized?

抱歉,如果标题不够清楚。 这是我的查询:

SELECT
    '>200000 €' as amount,
    Q1.asset as inbound,
    Q2.asset as outbound,
    Q3.asset as inside
FROM
    (
    SELECT COUNT(amount* base_rate) as asset
    FROM user_wallet_movement
    WHERE status = 'execute'
        AND direction = 'inbound'
        AND to_address is null
        AND mov_date > '2020-01-07'
        AND mov_date < '2021-06-30'
        AND amount* base_rate > 200000
        ) AS Q1
JOIN
        (
    SELECT COUNT(amount* base_rate) as asset
    FROM user_wallet_movement
    WHERE status = 'execute'
        AND direction = 'outbound'
        AND to_address is null
        AND mov_date > '2020-01-07'
        AND mov_date < '2021-06-30'
        AND amount* base_rate > 200000
        ) AS Q2
JOIN 
        (
    SELECT COUNT(amount* base_rate) as asset
    FROM user_wallet_movement
    WHERE status = 'execute'
        AND to_address is not null
        AND mov_date > '2020-01-07'
        AND mov_date < '2021-06-30'
        AND amount* base_rate > 200000
        ) AS Q3

如您所见,我加入了三个具有某些共同条件的查询。 我的问题是: 是否可以只写一次常见条件?

您可以使用case表达式

select
    '>200000 €' as amount
    sum(case when direction = 'inbound' then amount* base_rate else 0 end) as inbound_asset,
    sum(case when direction = 'outbound' then amount* base_rate else 0 end) as outbound_asset,
    sum(case when direction = 'execute' then amount* base_rate else 0 end) as execute_asset
FROM user_wallet_movement
WHERE to_address is not null
AND mov_date > '2020-01-07'
AND mov_date < '2021-06-30'
AND amount* base_rate > 200000

我不清楚你的示例查询的意图,所以我的回答可能不会产生你正在寻找的结果。我很困惑为什么涉及 COUNT() 而不是 SUM()

在任何情况下,您都可以应用条件聚合,因为所有值都来自同一个 table。这里不需要 JOIN。

如果您尝试计算所有符合某些不同标准的> 200000交易,您可以这样做:

SELECT
    '>200000 €' as amount,
    SUM(CASE WHEN direction = 'inbound' AND to_address is null 
        THEN 1 ELSE 0 END) AS inbound,
    SUM(CASE WHEN direction = 'outbound' AND to_address is null 
        THEN 1 ELSE 0 END) AS outbound,
    SUM(CASE WHEN to_address is not null 
        THEN 1 ELSE 0 END) AS inside
FROM user_wallet_movement
WHERE 
    (amount*base_rate) > 200000
    AND status = 'execute' 
    AND mov_date > '2020-01-07'
    AND mov_date < '2021-06-30'

如果您想要所有交易的总和以及超过 inbound/outbound/inside 的小计,您可以这样做:

SELECT
    SUM(amount*base_rate) as total,
    SUM(CASE WHEN direction = 'inbound' AND to_address is null 
        THEN amount*base_rate ELSE 0 END) AS inbound,
    SUM(CASE WHEN direction = 'outbound' AND to_address is null 
        THEN amount*base_rate ELSE 0 END) AS outbound,
    SUM(CASE WHEN to_address is not null 
        THEN amount*base_rate ELSE 0 END) AS inside
FROM user_wallet_movement
WHERE 
    AND status = 'execute' 
    AND mov_date > '2020-01-07'
    AND mov_date < '2021-06-30'