我在Postgresql中遇到'高级'(按我的标准)查询时遇到问题,我不确定应该如何寻找答案(关键字等)。我查看了Postgresql手册中的示例,并搜索了stackOverflow中的类似线程,但无济于事......
我有两个表:一个有账单,一个有交易,我要输出的表只包含那些1)比账单更新的交易,2)低于或等于账单3)on特定账户或以现金支付。
这个查询就是这样,但我猜它可以优化:
((SELECT * FROM transactions
WHERE amount = to_number('$bill_amount','99999999D99')
AND acc_int = 'cash'
AND date > to_date('$bill_date', 'YYYY-MM-DD'))
UNION
(SELECT * FROM transactions
WHERE amount = to_number('$bill_amount','99999999D99')
AND acc_int = 'xxx-xxxxxxx-xx'
AND date > to_date('$bill_date', 'YYYY-MM-DD'))
ORDER BY date DESC)
UNION
((SELECT * FROM transactions
WHERE amount < to_number('$bill_amount','99999999D99')
AND acc_int = 'cash'
AND date > to_date('$bill_date', 'YYYY-MM-DD'))
UNION
(SELECT * FROM transactions
WHERE amount < to_number('$bill_amount','99999999D99')
AND acc_int = 'xxx-xxxxxxx-xx'
AND date > to_date('$bill_date', 'YYYY-MM-DD'))
ORDER BY date DESC)
如果我可以简单地将OR
添加到'acc_int'条件而不会扰乱其他条件,则可以合并前两个选择。我认为这应该通过使用括号来完成,但它似乎不起作用。
此外,我想对结果进行排序,以便首先所有交易等于账单上的金额,然后按日期计算较低的金额 - 这就是为什么我将前两个选项与最后两个选项组合但使用{{ 1}}似乎扰乱了排序。
任何洞察力的THX(欢迎回答或链接到好的资源!)
答案 0 :(得分:1)
或许这样的事情:
SELECT * FROM transactions
WHERE amount <= to_number('$bill_amount','99999999D99')
AND acc_int IN ('cash', 'xxx-xxxxxxx-xx')
AND date = to_date('$bill_date', 'YYYY-MM-DD')
ORDER BY date DESC
答案 1 :(得分:1)
完整的查询可能如下所示:
SELECT *
FROM transactions
WHERE amount <= to_number('$bill_amount','99999999D99')
AND acc_int IN ('cash', 'xxx-xxxxxxx-xx')
AND date > to_date('$bill_date', 'YYYY-MM-DD')
ORDER BY
(amount <> to_number('$bill_amount','99999999D99'))
, date DESC
FALSE
在TRUE
之前排序,这就是我在<>
表达式中拥有ORDER BY
运算符的原因。
请注意,在原始查询中UNION
会删除重复的行。如果您的表中没有完整的重复项,结果是相同的(并且UNION ALL
将是更好的选择)。如果这样做,请添加DISTINCT
子句:
SELECT DISTINCT * ...
您认为OR
似乎不适合您。但它应该。这个......
AND acc_int IN ('cash', 'xxx-xxxxxxx-xx')
..完全等同于:
AND (acc_int = 'cash' OR acc_int = 'xxx-xxxxxxx-xx')
实际上,查询规划器会将第一个表单重写为第二个表单。