如果在oracle sql中将value设置为null,则make join

时间:2015-06-26 04:40:12

标签: sql oracle

我需要你身边的帮助:

我有两个表t1和t2,数据如下:

表t1

ID  PROP_ID County_code prop_type
1   abc     IE          A
2   bcd     US          P
3   cde     CA          P
4   def     IND         P
5   efg     CHINA       P

表T2

ID  PROP_IND    PROD_ID Amount
10  A                   200
20  P           US      300
30  P           CA      400
40  P           IND     500
50  P           CHINA   600
60  P           700
表t2中的

1 prop_id为Prop_ind A null,prop_id p为1。

我正在这两个表之间进行连接,如下所示:

decode(t1.prop_type,'A',t1.prop_id,'P',t1.country_code) = 
NVL(t2.prop_id, decode(t2.prop_ind,'A',t1.prop_id,'P',t1.country_code))

但是这个连接给了我不正确的结果。对于prop_ind的null prop_id,表t2中的P和P是默认值。

select * 
from t1,t2 
where decode(t1.prop_type,'A',t1.prop_id,'P',t1.county_code) = NVL(t2.prop_id, decode(t2.prop_ind,'A',t1.prop_id,'P',t1.county_code)) 

这个查询给了我9条记录但是我只看了5条记录 - user2862073 7分钟前

输出来自:

ID  PROP_ID COUNTY_CODE PROP_TYPE   ID  PROP_IND    PROP_ID AMOUNT 
3   cde CA  P   60  P   -   700 
3   cde CA  P   30  P   CA  400 
5   efg CHINA   P   50  P   CHINA   600 
5   efg CHINA   P   60  P   -   700 
1 abc   IE  A   10  A   -   200 
4   def IND P   40  P   IND 500 
4   def IND P   60  P   -   700 
2   bcd US  P   60  P   -   700 
2   bcd US  P 20    P   US  300 

然而,我只看了5条记录,它应该是

ID  PROP_ID County_code prop_type   Amount 
1   abc IE  A   200 
2   bcd US  P   300 
3   cde CA  P   400 
4   def IND P   500 
5   efg CHINA   P   600 

请建议我如何以正确的方式加入。

3 个答案:

答案 0 :(得分:0)

这必然会发生。

例如:

select  Decode(t1.prop_type, 'A', t1.prop_id, 
                            'P', t1.county_code) from t1;

给你

abc
US
CA
IND
CHINA

尽管

select  Nvl(t2.prop_id, 
Decode(t2.prop_ind, 'A', t1.prop_id, 
                    'P', t1.county_code)) from t1,t2;

这会给你

abc
US
CA
IND
CHINA
IE
bcd
US
CA
IND
CHINA
US
cde
US
CA
IND
CHINA
CA
def
US
CA
IND
CHINA
IND
efg
US
CA
IND
CHINA
CHINA

由于在t1和t2中没有要连接的唯一列,因此它继续进行6 * 5 = 30行的笛卡尔连接。所以T2中的最后一行将无法在T1中找到一个匹配。

因此,当你运行

SELECT t1.id, 
       t1.prop_id, 
       t1.county_code, 
       t1.prop_type, 
       t2.amount 
FROM   t1, 
       t2 
WHERE  Decode(t1.prop_type, 'A', t1.prop_id, 
                            'P', t1.county_code) = Nvl(t2.prop_id, 
Decode(t2.prop_ind, 'A', t1.prop_id, 
                    'P', t1.county_code)) ;

你得到了

ID  PROP_ID COUNTY_CODE PROP_TYPE   AMOUNT
1   abc IE  A   200
2   bcd US  P   300
2   bcd US  P   700
3   cde CA  P   400
3   cde CA  P   700
4   def IND P   500
4   def IND P   700
5   efg CHINA   P   600
5   efg CHINA   P   700

可能会这样做

如果您想避免硬编码,则需要从内联查询中选择解码选项

SELECT t1.id, 
       t1.prop_id, 
       t1.county_code, 
       t1.prop_type,
       nvl (t2.amount,decode(t1.prop_type,'A',200,'P',700))
       from t1 left outer join t2 on t1.prop_type = t2.PROP_IND
       and t1.County_code = t2.prop_id
       order by t1.id;

答案 1 :(得分:0)

我认为你需要这个join

select t1.id, t1.prop_id, t1.county_code, t1.prop_type, t2.amount 
  from t1 join t2
    on (t1.prop_type = 'A' and t2.prop_ind='A' and t2.prod_id is null) 
    or (t1.prop_type = 'P' and t1.county_code = t2.prod_id)

输出:

        ID PROP_ID COUNTY_CODE PROP_TYPE     AMOUNT
---------- ------- ----------- --------- ----------
         1 abc     IE          A                200 
         2 bcd     US          P                300 
         3 cde     CA          P                400 
         4 def     IND         P                500 
         5 efg     CHINA       P                600

答案 2 :(得分:0)

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE t1 ( ID,  PROP_ID, County_code, prop_type ) AS
          SELECT 1, 'abc', 'IE', 'A' FROM DUAL
UNION ALL SELECT 2, 'bcd', 'US', 'P' FROM DUAL
UNION ALL SELECT 3, 'cde', 'CA', 'P' FROM DUAL
UNION ALL SELECT 4, 'def', 'IND', 'P' FROM DUAL
UNION ALL SELECT 5, 'efg', 'CHINA', 'P' FROM DUAL;

CREATE TABLE t2 ( ID,  PROP_IND,    PROD_ID, Amount ) AS
          SELECT 10, 'A', NULL, '200' FROM DUAL
UNION ALL SELECT 20, 'P', 'US', '300' FROM DUAL
UNION ALL SELECT 30, 'P', 'CA', '400' FROM DUAL
UNION ALL SELECT 40, 'P', 'IND', '500' FROM DUAL
UNION ALL SELECT 50, 'P', 'CHINA', '600' FROM DUAL
UNION ALL SELECT 60, 'P', NULL, '700' FROM DUAL

查询1

select t1.*, t2.AMOUNT 
from t1 INNER JOIN t2
     ON (    t1.PROP_TYPE = t2.PROP_IND
         AND (    ( t1.PROP_TYPE = 'P' AND t1.County_Code = t2.prod_id )
              OR  ( t1.PROP_TYPE = 'A' AND (t1.PROP_ID = t2.PROD_ID OR t2.PROD_ID IS NULL ) )
             )
        )

<强> Results

| ID | PROP_ID | COUNTY_CODE | PROP_TYPE | AMOUNT |
|----|---------|-------------|-----------|--------|
|  1 |     abc |          IE |         A |    200 |
|  2 |     bcd |          US |         P |    300 |
|  3 |     cde |          CA |         P |    400 |
|  4 |     def |         IND |         P |    500 |
|  5 |     efg |       CHINA |         P |    600 |