[英]Select case with multiple columns along with other columns in Oracle?
Consider the following tables考虑下表
ID_TYPE ID_TYPE
ID ![]() |
TYPE![]() |
---|---|
1 ![]() |
3 ![]() |
2 ![]() |
3 ![]() |
3 ![]() |
1 ![]() |
4 ![]() |
2 ![]() |
5 ![]() |
2 ![]() |
ID_HISTORY ID_HISTORY
DEBIT_ID ![]() |
DEBIT_LOCATION ![]() |
AMOUNT![]() |
CREDIT_ID ![]() |
CREDIT_LOCATION ![]() |
MONTH![]() |
---|---|---|---|---|---|
3 ![]() |
LOC1![]() |
100 ![]() |
1 ![]() |
LOC5 ![]() |
MAY![]() |
4 ![]() |
LOC2 ![]() |
200 ![]() |
3 ![]() |
LOC6 ![]() |
MAY![]() |
2 ![]() |
LOC3 ![]() |
300 ![]() |
5 ![]() |
LOC7 ![]() |
MAY![]() |
1 ![]() |
LOC4 ![]() |
400 ![]() |
3 ![]() |
LOC8 ![]() |
JUNE![]() |
3 ![]() |
LOC9 ![]() |
500 ![]() |
2 ![]() |
LOC10 ![]() |
JUNE![]() |
Now suppose I want to fetch all rows from ID_HISTORY in the MONTH of MAY, and result should contain only these columns:现在假设我想在五月的 MONTH 中从 ID_HISTORY 中获取所有行,结果应该只包含这些列:
Id, Location, Amount
Cases:案例:
DEBIT_ID
is of TYPE
= 3 in the ID_TYPE
table, then pick DEBIT_ID
as "Id", else pick CREDIT_ID
as "Id"DEBIT_ID
是TYPE
在= 3 ID_TYPE
表,然后选择DEBIT_ID
为“ID”,否则挑CREDIT_ID
为“ID”DEBIT_ID
is of TYPE
3 in the ID_TYPE
table, then pick DEBIT_LOCATION
as "Location", else pick CREDIT_LOCATION
as "Location"ID_TYPE
表中的DEBIT_ID
是TYPE
3,则选择DEBIT_LOCATION
作为“位置”,否则选择CREDIT_LOCATION
作为“位置” For example, above tables should result in the following:例如,上表应产生以下结果:
Id ![]() |
Location![]() |
Amount![]() |
---|---|---|
1 ![]() |
LOC5 ![]() |
100 ![]() |
2 ![]() |
LOC3 ![]() |
300 ![]() |
I know that something like the following should work:我知道类似以下内容应该有效:
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
)
But as you can see this will be inefficient as I have to basically duplicate the full case logic for each conditional columns.但是正如您所看到的,这将是低效的,因为我必须基本上为每个条件列复制完整的案例逻辑。 Also, this is no way "clean" in case there are a lot of similar columns.
此外,如果有很多类似的列,这也不是“干净”的方法。
Also, if the case logic is complex, it will be inefficient even further.此外,如果案例逻辑很复杂,则效率会更低。 It would be better if i could select multiple columns in
THEN
/ ELSE
cases.如果我可以在
THEN
/ ELSE
情况下选择多个列会更好。 I tried doing that, but it just gives me "ORA-00913: too many values" error.我尝试这样做,但它只会给我“ORA-00913:值太多”错误。
What would be the optimized version?优化后的版本是什么?
You could use a join to remove the sub-queries:您可以使用连接来删除子查询:
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.