一个查询中的条件连接

时间:2015-03-26 17:40:45

标签: sql oracle11g

有三个表格,数据如下:

交易的数量:

enter image description here

GRD_TIME_ZONE:

enter image description here

PRI_TIME_ZONE:

enter image description here

我必须获得time_zone值。为此我有两个选择:

选项1:

SELECT trade_id, t.grd_exch_cd, time_zone_name
FROM trades t
JOIN grd_time_zone gtz ON t.grd_exch_cd = gtz.grd_exch_cd;

enter image description here

选项2:

SELECT t.trade_id, t.grd_exch_cd, time_zone_name
FROM trades t
JOIN pri_time_zone ptz ON t.trade_id = ptz.trade_id;

enter image description here

如果您注意到,我没有获得所有3笔交易的time_zone值。

我的要求是使用以下逻辑将上述查询合并到一个查询中:

  • 如果交易表中的grd_exch_cd映射到grd_time_zone表中的一个且只有一个time_zone,则从那里获取值。

  • 如果交易表中的grd_exch_cd为NULL,请从pri_time_zone表中获取time_zone值。

  • 如果交易表中的grd_exch_cd映射到grd_time_zone表中的多个time_zone,则从pri_time_zone表中获取time_zone值。

SELECT trade_id, t.grd_exch_cd, time_zone_name
FROM trades t
-- if grd_exch_cd is mapped to one time_zone in grd_time_zone
JOIN grd_time_zone gtz ON t.grd_exch_cd = gtz.grd_exch_cd
-- else if grd_exch_cd is NULL or mapped to more than one time_zone in grd_time_zone
JOIN pri_time_zone ptz ON t.trade_id = ptz.trade_id;

有人可以帮助设计执行条件联接的查询。

2 个答案:

答案 0 :(得分:1)

我倾向于在聚合查询中使用外连接来完成此任务:

SELECT t.trade_id, 
       t.grd_exch_cd, 
       CASE Count(DISTINCT gtz.time_zone_name) 
         WHEN 1 THEN Max(gtz.time_zone_name) 
         ELSE Max(ptz.time_zone_name) 
       END 
FROM   trades t 
       left join grd_time_zone gtz 
              ON t.grd_exch_cd = gtz.grd_exch_cd 
       left join pri_time_zone ptz 
              ON t.trade_id = ptz.trade_id 
GROUP  BY t.trade_id, 
          t.grd_exch_cd
  • 我们正在使用MAX来合并许多值。如果有多个gtz.time_zone_name,那么无论如何我们都不会使用该值,因此我们选择哪一个并不重要。
  • 如果没有相应的gtz.time_zone_name条目,
  • grd_time_zone将返回零,因此无需明确检查null
  • left join(也称为外部联接)就是您所说的"从trades向我提供所有内容,但只提供来自grd_time_zone"的匹配记录。在SQL中。

答案 1 :(得分:0)

这是一个首先加入交易和pri_time_zone表的查询,然后将结果与另一个查询结合起来,该查询将获取完全匹配的所有时区。只是一个想法:

SELECT T.TRADEID ,
       T.GRD_EXCH_CD ,
       PTZ.TIME_ZONE_NAME
FROM   TRADES T
       INNER JOIN PRI_TIME_ZONE PTZ
         ON T.TRADEID = PTZ.TRADEID
UNION
SELECT T.TRADEID, 
       GTZ.GRD_EXCH_CD, 
       GTZ.TIME_ZONE_NAME
FROM   TRADES T  
       JOIN GRD_TIME_ZONE GTZ
          ON T.GRD_EXCH_CD = GTZ.GRD_EXCH_CD
WHERE   T.TRADEID in 
                       (SELECT    T.TRADEID
                        FROM      TRADES T  
                                  JOIN GRD_TIME_ZONE GTZ
                                    ON T.GRD_EXCH_CD = GTZ.GRD_EXCH_CD
                        GROUP BY T.TRADEID
                        HAVING COUNT(*) =1)