【问题标题】:Selecting default row if no rows return with join condition values from other tables如果没有行返回其他表的连接条件值,则选择默认行
【发布时间】:2020-04-12 15:49:31
【问题描述】:

我有两张桌子ORDERSRATE

CREATE TABLE ORDERS
(   ID NUMBER(12,0), 
    DOW NUMBER(12,0), 
    COUNT NUMBER(12,0)
);

CREATE TABLE RATE
(   ID NUMBER(12,0), 
    DOW NUMBER(12,0), 
    RATE NUMBER(12,0)
);
INSERT INTO ORDERS (ID, DOW, COUNT) VALUES ('1', '1', '5');
INSERT INTO ORDERS (ID, DOW, COUNT) VALUES ('1', '3', '7');
INSERT INTO ORDERS (ID, DOW, COUNT) VALUES ('2', '1', '2');
INSERT INTO RATE (ID, DOW, RATE) VALUES ('1', '1', '10');
INSERT INTO RATE (ID, DOW, RATE) VALUES ('1', '2', '20');
INSERT INTO RATE (ID, DOW, RATE) VALUES ('1', '0', '50');

并且我想获取表 ORDERS 中所有订单的成本,假设默认费率为 10 用于那些在 RATE 表中没有相应 ID 费率的订单,并且如果 ID 为RATE 表中可用,但该 id 的某个 dow 没有可用的汇率,则该 id 始终可以使用 dow 0 的默认汇率。

对于上面的示例,预期如下:

id  dow   cost
--------------
1    1     50
1    3     350
2    1     20

请注意,id=1 和 dow=3 的 350 来自计数 7 乘以 id=1 和 dow=0 的比率 50,因为表中没有 id=1 和 dow=3 的比率。我试过以下没有运气:

SELECT o.id, o.dow, o.count*(coalesce(r.rate, 10)) as cost
FROM orders o
left join rate r
on r.id = o.id
and  r.dow = o.dow
;

以下有编译错误:

ORA-00904: "O"."DOW": 标识符无效

  1. 00000 - “%s:无效标识符”
SELECT o.id ,o.dow ,o.count * (coalesce(r.rate, 10)) cost
FROM orders o
LEFT JOIN (
    SELECT id, dow, rate
    FROM rate
    WHERE id = o.id
        AND dow = o.dow
    
    UNION ALL
    
    SELECT id ,dow ,rate
    FROM rate
    WHERE id = o.id
        AND dow = 0
        AND NOT EXISTS (
            SELECT 1
            FROM rate
            WHERE id = o.id
                AND dow = o.dow
            )
    ) r
    ON r.id = o.id
;

有人可以帮忙查询吗?

【问题讨论】:

  • 我认为 2 应该是 100?
  • 在您发布的最后一个 SQL 查询中,尝试为 rate 表分配一个别名。我猜 Oracle 解析器不够聪明,无法处理一个有别名的表和另一个没有别名的表。
  • @EdBangga,id 2 没有速率,因此使用默认速率,比如 10:2*10 = 20。
  • @Abra,给rate表添加别名后不起作用。

标签: sql oracle join conditional-statements default-value


【解决方案1】:

您可以使用多个outer joinsRATE 表来获取所需的结果,如下所示:

SQL> SELECT
  2      O.ID,
  3      O.DOW,
  4      O.COUNT * COALESCE(R.RATE, RD.RATE) AS COST
  5  FROM
  6      ORDERS O
  7      LEFT JOIN RATE R ON ( O.DOW = R.DOW )
  8      LEFT JOIN RATE RD ON ( R.ID IS NULL
  9                             AND RD.DOW = 0 )
 10  ORDER BY O.ID;

        ID        DOW       COST
---------- ---------- ----------
         1          1         50
         1          3        350
         2          1         20

SQL>

干杯!!

【讨论】:

  • 太棒了! RATE 表的第二个左连接用于在 ID 匹配但没有 DOW 的速率时获取默认值。我做了一些小改动以满足原始要求:SELECT O.ID, O.DOW, O.COUNT * COALESCE(R.RATE, RD.RATE, 10) AS COST FROM ORDERS O LEFT JOIN RATE R ON ( O.ID = R.ID AND O.DOW = R.DOW ) LEFT JOIN RATE RD ON ( O.ID = RD.ID AND RD.DOW = 0 ) ORDER BY O.ID; 谢谢@Tejash 的帮助!
猜你喜欢
  • 2018-12-12
  • 1970-01-01
  • 2011-04-20
  • 2018-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-30
  • 1970-01-01
相关资源
最近更新 更多