针对提取值的 Oracle sql 连接

Posted

技术标签:

【中文标题】针对提取值的 Oracle sql 连接【英文标题】:Oracle sql join against extracted values 【发布时间】:2016-02-03 12:16:21 【问题描述】:

我希望协调来自 2 个不同表的数据,在这些表中我需要执行连接和 substr 以创建可用于执行匹配的列。以下单独的查询反映了每个表中产生的 select 语句将sitenn.zonenn(例如site12.zone20)反映为节点名的匹配值。

SELECT distinct(REGEXP_SUBSTR(B.NODE_NAME,'*site*.*')) as nodename
FROM OPC_ACT_MESSAGES A,OPC_NODE_NAMES B 
WHERE A.MESSAGE_GROUP = 'Ebts_Status_Alarms' 
AND A.SEVERITY <> 2 
AND A.NODE_ID = B.NODE_ID;

SELECT 'site'||site_id||'.zone'||zone_id as nodename
FROM aw_active_alarms 
GROUP BY site_id,zone_id;

我需要编写一个查询,从一个表中选择另一个表中不存在的所有节点名。

【问题讨论】:

【参考方案1】:

使用left join 找到它。它比minus,not in,not exists等更快。

SELECT a.nodename 
FROM   (SELECT DISTINCT( regexp_substr(B.node_name, '*site*.*') ) AS nodename 
        FROM   opc_act_messages A, 
               opc_node_names B 
        WHERE  A.message_group = 'Ebts_Status_Alarms' 
               AND A.severity <> 2 
               AND A.node_id = B.node_id
        ) a 
LEFT JOIN 
        (SELECT 'site' 
                         || site_id 
                         || '.zone' 
                         || zone_id AS nodename 
                  FROM   aw_active_alarms 
                  GROUP  BY site_id, 
                            zone_id
        ) b 
ON a.nodename = b.nodename 
WHERE  b.nodename IS NULL 

【讨论】:

谢谢,这正是我正在寻找的(正如其他建议一样)并采用了最佳实践。只有一个问题,我不清楚最后一行的目的——其中 b.nodename 为空 如果你不给WHERE b.nodename IS NULL,那么你会得到所有的a.nodename。对于存在于a 而不是b 中的记录,从ableft join 将给出b.nodename 作为null。您只能获取这些记录来获取输出,因此是 where 条件。【参考方案2】:

一种简单的方法:使用MINUS

SELECT distinct(REGEXP_SUBSTR(B.NODE_NAME,'*site*.*')) as nodename
FROM OPC_ACT_MESSAGES A,OPC_NODE_NAMES B 
WHERE A.MESSAGE_GROUP = 'Ebts_Status_Alarms' 
AND A.SEVERITY <> 2 
AND A.NODE_ID = B.NODE_ID 
MINUS
SELECT 'site'||site_id||'.zone'||zone_id as nodename
FROM aw_active_alarms 
GROUP BY site_id,zone_id;

【讨论】:

【参考方案3】:

这行得通吗?

WITH t1
     AS (SELECT DISTINCT
                (REGEXP_SUBSTR (B.NODE_NAME, '*site*.*')) AS nodename
           FROM OPC_ACT_MESSAGES A, OPC_NODE_NAMES B
          WHERE     A.MESSAGE_GROUP = 'Ebts_Status_Alarms'
                AND A.SEVERITY <> 2
                AND A.NODE_ID = B.NODE_ID),
     t2
     AS (  SELECT 'site' || site_id || '.zone' || zone_id AS nodename
             FROM aw_active_alarms
         GROUP BY site_id, zone_id)
SELECT *
  FROM t1
 WHERE t1.nodename NOT IN (SELECT nodename FROM t2)

【讨论】:

以上是关于针对提取值的 Oracle sql 连接的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SQL 将日期维度表与另一个关于日期值的表连接起来

java连接Oracle数据库,从ResultSet中提取数据出现java.sql.sqlException结果集已耗尽

关于使用啥 pl-sql 从 Oracle 10G 数据库中提取大量记录(六百万)的任何建议,并从多个表中进行连接? [复制]

Maximo/Oracle SQL 语句从连接表中返回不需要的数据

Oracle:使用其他表中的值进行更新

Oracle 连接大列表