[英]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.