在复杂条件下加入表格

时间:2016-07-01 07:21:52

标签: sql oracle

我有两张桌子:

CREATE TABLE TableA ( Col1, Col2, Col3, Col4 ) AS
  SELECT 'a', 'b',  1, 'ABC' FROM DUAL UNION ALL 
  SELECT 'a', 'b',  2, 'DEF' FROM DUAL UNION ALL 
  SELECT 'a', 'b', 15, 'GHI' FROM DUAL UNION ALL 
  SELECT 'c', 'd', 17, 'JKL' FROM DUAL UNION ALL 
  SELECT 'c', 'd', 10, 'MNO' FROM DUAL UNION ALL 
  SELECT 'c', 'd',  6, 'PQR' FROM DUAL;

CREATE TABLE TableB ( Col1, Col2, Col3 ) AS
  SELECT 'a', 'b',  1 FROM DUAL UNION ALL 
  SELECT 'a', 'b',  4 FROM DUAL UNION ALL 
  SELECT 'a', 'b', 12 FROM DUAL UNION ALL 
  SELECT 'c', 'd',  9 FROM DUAL UNION ALL 
  SELECT 'c', 'd', 12 FROM DUAL UNION ALL 
  SELECT 'c', 'd',  3 FROM DUAL;

输出是 A.COL1, A.COL2,B.COL3A.COL4b.col3的值是低于a.col3的最大值。 TableC是输出表,如下所示。

TableC
+------+------+------+------+
| Col1 | Col2 | Col3 | Col4 |
+------+------+------+------+
| a    | b    |    1 | ABC  |
| a    | b    |    1 | DEF  |
| a    | b    |   12 | GHI  |
| c    | d    |   12 | JKL  |
| c    | d    |    9 | MNO  |
| c    | d    |    3 | PQR  |
+------+------+------+------+

3 个答案:

答案 0 :(得分:0)

只需为col1,col2和col4值执行JOIN。有一个相关的子查询返回最小TableB.col3小于TableA.col3:

select ta.col1, ta.col2, (select max(col3) from TableB
                          where col1 = t1.col1 and col2 = t1.col2 and col3 < ta.col3),
       tb.col4
from TableA ta
  join TableB tb on ta.col1 = tb.col1 and ta.col2 = tb.col2

答案 1 :(得分:0)

一种可能性是加入一个简单的连接子句,并通过where子句处理其余部分。此查询适用于您的示例:

SELECT a.col1, a.col2, b1.col3, a.col4
FROM a JOIN b b1 ON a.col1 = b1.col1 AND a.col2 = b1.col2
WHERE b1.col3 <= a.col3 
  AND NOT EXISTS (
     SELECT * FROM b c 
     WHERE c.col1 = b1.col1 AND c.col2 = b1.col2 
        AND c.col3 > b1.col3 AND c.col3 <= a.col3
     )

答案 2 :(得分:0)

在这种情况下,使用相关子查询而不是连接表更简单:

<强>查询

SELECT A.Col1,
       A.Col2,
       ( SELECT MAX( B.Col3 )
         FROM   TableB B
         WHERE  A.Col1 = B.Col1
         AND    A.Col2 = B.Col2
         AND    A.Col3 > B.Col3 ) AS Col3,
       A.Col4
FROM   TableA A;

<强>输出

COL1 COL2 COL3 COL4
---- ---- ---- ----
a    b    NULL ABC
a    b       1 DEF
a    b      12 GHI
c    d      12 JKL
c    d       9 MNO
c    d       3 PQR

如果您希望第一行COL3等于1,那么您需要使用>=而不是>(但这不是您所描述的逻辑文本)。

如果您要过滤掉NULL行,请使用:

SELECT *
FROM   ( ... above query ... )
WHERE  Col3 IS NOT NULL;