简体   繁体   English

在 Oracle 中选择多列和其他列的案例?

[英]Select case with multiple columns along with other columns in Oracle?

Consider the following tables考虑下表

ID_TYPE ID_TYPE

ID ID TYPE类型
1 1 3 3
2 2 3 3
3 3 1 1
4 4 2 2
5 5 2 2

ID_HISTORY ID_HISTORY

DEBIT_ID DEBIT_ID DEBIT_LOCATION DEBIT_LOCATION AMOUNT数量 CREDIT_ID CREDIT_ID CREDIT_LOCATION CREDIT_LOCATION MONTH
3 3 LOC1位置1 100 100 1 1 LOC5 LOC5 MAY可能
4 4 LOC2 LOC2 200 200 3 3 LOC6 LOC6 MAY可能
2 2 LOC3 LOC3 300 300 5 5 LOC7 LOC7 MAY可能
1 1 LOC4 LOC4 400 400 3 3 LOC8 LOC8 JUNE六月
3 3 LOC9 LOC9 500 500 2 2 LOC10 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:案例:

  • If the DEBIT_ID is of TYPE = 3 in the ID_TYPE table, then pick DEBIT_ID as "Id", else pick CREDIT_ID as "Id"如果DEBIT_IDTYPE在= 3 ID_TYPE表,然后选择DEBIT_ID为“ID”,否则挑CREDIT_ID为“ID”
  • Similarly, If the 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_IDTYPE 3,则选择DEBIT_LOCATION作为“位置”,否则选择CREDIT_LOCATION作为“位置”

For example, above tables should result in the following:例如,上表应产生以下结果:

Id ID Location地点 Amount数量
1 1 LOC5 LOC5 100 100
2 2 LOC3 LOC3 300 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM