连接表按日期过滤

时间:2019-08-03 11:36:38

标签: sql postgresql left-join

我有2张桌子。第一-钱包,第二-钱包历史。现在,我可以根据每个钱包的所有已完成的存款/提款总额进行选择。

Sql代码看起来像这样:

SELECT w.*, wh.deposit, wh2.withdrawal, wh3.pending
FROM wallets w
LEFT JOIN (
    SELECT wallet_id, SUM(amount) deposit
    FROM wallet_histories
    WHERE type = 'Deposit'
        AND status = 'Completed'
        AND timestamp BETWEEN '2019-08-02 00:00:00+00' AND '2019-08-03 00:00:00+00'
    GROUP BY wallet_id
) wh ON w.id = wh.wallet_id
LEFT JOIN (
    SELECT wallet_id, SUM(amount) withdrawal
    FROM wallet_histories
    WHERE type = 'Withdrawal'
        AND status = 'Completed'
        AND timestamp BETWEEN '2019-08-02 00:00:00+00' AND '2019-08-03 00:00:00+00'
    GROUP BY wallet_id
) wh2 ON w.id = wh2.wallet_id
LEFT JOIN (
    SELECT wallet_id, SUM(amount) pending
    FROM wallet_histories
    WHERE status = 'Pending'
    GROUP BY wallet_id
) wh3 ON w.id = wh3.wallet_id

接下来,我需要进行选择,但要通过表钱包中的enabled_at字段进行过滤。 我应该在WHERE中再作一个条件: AND timestamp >= w.enabled_at 但出现错误

LINE 10:       AND timestamp >= w.enabled_at
                                ^
HINT:  There is an entry for table "w", but it cannot be referenced from this part of the query.

我如何避免此错误(也许完全重建查询)? 预先谢谢你。

1 个答案:

答案 0 :(得分:0)

您需要在每个子查询中添加条件。聚合的结果没有enabled_at,因此外部查询中的列不可用-在onwhere子句中。

也就是说,您可以使用条件聚合来大大简化查询:

SELECT wallet_id,
       SUM(amount) FILTER (WHERE type = 'Deposit') as deposit
       SUM(amount) FILTER (WHERE type = 'Withdrawal') as withdrawal,
       SUM(amount) FILTER (WHERE status = 'Pending') as pending
FROM wallet_histories
WHERE (type IN ('Deposit', 'Withdrawal') AND
       status = 'Completed' AND
       timestamp >= '2019-08-02' AND
       timestamp < '2019-08-03'
      ) OR
      status = 'Pending'
GROUP BY wallet_id;

这可能使添加其他条件更加容易。