[英]Select case with multiple columns along with other columns in Oracle?
考慮下表
ID_TYPE
ID | 類型 |
---|---|
1 | 3 |
2 | 3 |
3 | 1 |
4 | 2 |
5 | 2 |
ID_HISTORY
DEBIT_ID | DEBIT_LOCATION | 數量 | CREDIT_ID | CREDIT_LOCATION | 月 |
---|---|---|---|---|---|
3 | 位置1 | 100 | 1 | LOC5 | 可能 |
4 | LOC2 | 200 | 3 | LOC6 | 可能 |
2 | LOC3 | 300 | 5 | LOC7 | 可能 |
1 | LOC4 | 400 | 3 | LOC8 | 六月 |
3 | LOC9 | 500 | 2 | LOC10 | 六月 |
現在假設我想在五月的 MONTH 中從 ID_HISTORY 中獲取所有行,結果應該只包含這些列:
Id, Location, Amount
案例:
DEBIT_ID
是TYPE
在= 3 ID_TYPE
表,然后選擇DEBIT_ID
為“ID”,否則挑CREDIT_ID
為“ID”ID_TYPE
表中的DEBIT_ID
是TYPE
3,則選擇DEBIT_LOCATION
作為“位置”,否則選擇CREDIT_LOCATION
作為“位置”例如,上表應產生以下結果:
ID | 地點 | 數量 |
---|---|---|
1 | LOC5 | 100 |
2 | LOC3 | 300 |
我知道類似以下內容應該有效:
SELECT
(CASE
WHEN (Tab.DEBIT_ID IN (
SELECT ID
FROM ID_TYPE Typ
WHERE Typ.TYPE = 3)
) THEN Tab.DEBIT_ID
ELSE Tab.CREDIT_ID END
) "Id",
(CASE
WHEN (Tab.DEBIT_ID IN (
SELECT ID
FROM ID_TYPE Typ
WHERE Typ.TYPE = 3)
) THEN Tab.DEBIT_LOCATION
ELSE Tab.CREDIT_LOCATION END
) "Location",
Tab.AMOUNT "Amount"
FROM (
SELECT *
FROM ID_HISTORY Tab
WHERE Tab.MONTH = 'MAY'
--this block will be very complicated and contain complex multi-level queries to fetch data
)
但是正如您所看到的,這將是低效的,因為我必須基本上為每個條件列復制完整的案例邏輯。 此外,如果有很多類似的列,這也不是“干凈”的方法。
此外,如果案例邏輯很復雜,則效率會更低。 如果我可以在THEN
/ ELSE
情況下選擇多個列會更好。 我嘗試這樣做,但它只會給我“ORA-00913:值太多”錯誤。
優化后的版本是什么?
您可以使用連接來刪除子查詢:
SELECT CASE
WHEN typ.id IS NOT NULL
THEN h.debit_id
ELSE h.credit_id
END AS id,
CASE
WHEN typ.id IS NOT NULL
THEN h.debit_location
ELSE h.credit_location
END AS location,
h.AMOUNT
FROM (
SELECT *
FROM ID_HISTORY
WHERE MONTH = 'MAY'
-- this block will be very complicated and contain complex multi-level queries to fetch data
) h
LEFT OUTER JOIN (
SELECT id
FROM id_type
WHERE type = 3
) typ
ON (h.debit_id = typ.id)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.