使用AND / OR / UNION进行postgresql查询

时间:2012-01-19 18:55:52

标签: postgresql

我在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(欢迎回答或链接到好的资源!)

2 个答案:

答案 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
  • FALSETRUE之前排序,这就是我在<>表达式中拥有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')
    

实际上,查询规划器会将第一个表单重写为第二个表单。