2012-01-19 33 views
1

我在Postgresql中遇到了一個'高級'(通過我的標準)查詢的問題,而且我不知道應該如何查找答案(關鍵字等)。我已經查看了Postgresql手冊中的示例並搜索了stackoverflow以獲取類似的線程,但無濟於事...帶有AND/OR/UNION的postgresql查詢

我有兩個表:一個是賬單,另一個是事務,而我想輸出的表包含只有那些比1)更新的交易2)低於或等於特定賬戶上的賬單3)或以現金支付的交易。

這個查詢了這一點,但我想它可以進行優化:如果我可以簡單地增加一個OR到「acc_int'條件不擾亂別的

((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) 

前兩個選擇可以合併條件。我認爲這應該通過使用括號來完成,但它似乎沒有工作。

此外我想對結果進行排序,以便首先所有等於帳單上的金額,然後按日期計算的金額較低的交易 - 這就是爲什麼我將前兩個選擇與最後兩個選擇相結合,但使用UNION似乎打亂了排序。

THX對於任何見解(答案或鏈接到好的資源都歡迎!)

回答

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之前排序,這就是爲什麼我有th 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') 
    

事實上查詢規劃重寫第一形式到第二。

+0

THX - 這是一個 - 它完美的作品。我知道它可以完成,但被1個錯誤阻止(OR子句可能是錯誤的,因爲我認爲我按照你描述的方式嘗試了它),還有一件事我根本不知道(ORDER BY-指令)。 – zenlord

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 
+0

謝謝你 - 你的答案已經有效地減少了一半的查詢(將金額條件修改爲'WHERE amount BETWEEN 0 AND $ bill_amount'以避免負面結果。唯一剩下的問題是關於排序順序的問題:確切的金額匹配在上面和下面/部分金額以下 – zenlord

+0

您可以按金額訂購 –

+0

是的,我知道並且完全忘記了它。謝謝您的回答! – zenlord