【问题标题】:SQL (oracle) imposing hierarchy on where clauseSQL(oracle)对where子句施加层次结构
【发布时间】:2013-09-26 18:57:48
【问题描述】:

表名:REG_NBRS

STATE        CITY      COUNTRY   REG_NBR
------------------------------------------
ILLINOIS               USA       444333222
NEBRASKA               USA       111222333
             NEW YORK  USA       333444555
FLORIDA                USA       666222666
             TAMPA     USA       888333888

我有类似这样的数据,我需要获取该州或城市的 REG_NBR。如果该行与州和市都匹配,则优先考虑城市,并且如果与州或市都不匹配,那么我仍必须为 reg_nbr 列出带有 null 的行。 我试图提出一个查询,但没有取得太大的成功,因为我不知道如何在进行外部连接时强加一个优先级。

SELECT C.NAME, C.AGE, RN.REG_NBR
  FROM CUSTOMER C, REG_NBRS RN
 WHERE C.COUNTRY = RN.COUNTRY
   AND (C.STATE = RN.STATE OR C.CITY = RN.CITY)
   AND C.ID BETWEEN 1000 AND 2000

作为一个初学者,我不知道如何以这样的方式加入这两个表

  1. 它首先加入 STATE 和 City
  2. 但仍列出所有 1000 行
  3. 对那些非来自这些州或城市的注册号码置空
  4. 如果两者都匹配,则使用州的注册号码(即坦帕使用 666222666,即使我们可以找到 TAMPA 的条目)

如果这没有意义,我很抱歉,但我已尽力解释。我还尝试了左外连接和右外连接的不同组合,但不知道如何为 WHERE 组合施加层次结构。我想到了 UNIONS,但我认为即使是工会也会为坦帕的一位客户列出 2 行,其中包含两个 REG_NBR。 有什么建议吗?

为混乱的代码道歉,因为我正在使用(不是这样)智能手机发布这个问题。

【问题讨论】:

    标签: sql oracle join


    【解决方案1】:

    假设您在 (Country, State) 和 (Country, City) 中有唯一的键,您可以通过加入两次以简单的方式做到这一点:

    SELECT 
      C.NAME, C.AGE,
      COALESCE(RN1.REG_NBR, RN2.REG_NBR) AS REG_NBR
    FROM CUSTOMER C
    LEFT OUTER JOIN REG_NBRS RN1
      ON RN1.COUNTRY = RN1.COUNTRY
     AND RN1.STATE = C.STATE
    LEFT OUTER JOIN REG_NBRS RN2
      ON RN2.COUNTRY = C.COUNTRY 
     AND RN2.CITY = C.CITY 
    WHERE C.ID BETWEEN 1000 AND 2000
    

    此外,这应该比 OR 更快,数据库不太喜欢 OR(至少在适当的索引到位的情况下)。

    【讨论】:

    • 完美!!感谢您的回复.. 我之前不知道 Coalesce... 将我的复杂查询更改为 ANSI 标准并使用了您的技巧.. 谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 2011-05-04
    • 2017-07-03
    相关资源
    最近更新 更多