使用联接转换内联查询

时间:2018-07-18 13:10:03

标签: sql oracle

我试图替换当前的内联查询,并使用join替换相同的查询。但是,所得结果与实际结果有所不同。

SELECT CLM.ID,
       EL.ERAC_ACTP_CD,
       CLM.ELCT_ID,
       CLM.CLMBT_ID,
       DECODE(CLM.PROVIDER,
              NULL,
              (SELECT NVL(NAME, '')
                 FROM PROVIDER
                WHERE ID = PRVD_ID
                  AND EE_ID = CLM.EE_ID),
              CLM.PROVIDER) PROVIDER_NAME,
       CB.CLAIM_TYPE,
       EL.ACCOUNT_NO
  FROM ELECTION EL, CLAIM CLM, CLAIM_BATCH CB
 WHERE EL.ID = CLM.ELCT_ID
   AND CLM.ID = 1
   AND EL.EE_ID = 1
   AND EL.ID = CLM.ELCT_ID
   AND CB.ID = CLM.CLMBT_ID;

注意-CLM.PRVD_ID列值可以为空。

最初,我尝试使用内部联接使用以下查询。这不起作用,因为PRVD_ID可以为null。因此,我没有收到任何输出,而在原始查询中却收到了一行。

SELECT CLM.ID,
           EL.ERAC_ACTP_CD,
           CLM.ELCT_ID,
           CLM.CLMBT_ID,
DECODE(CLM.PROVIDER,
NULL,
PR.NAME,
CLM.PROVIDER) PROVIDER_NAME,
CB.CLAIM_TYPE,
EL.ACCOUNT_NO
FROM ELECTION EL, CLAIM CLM, CLAIM_BATCH CB, PROVIDER PR
WHERE EL.ID = CLM.ELCT_ID
AND CLM.ID = 1
AND EL.EE_ID = 1
AND EL.ID = CLM.ELCT_ID
AND CB.ID = CLM.CLMBT_ID  
AND  PR.ID = CLM.PRVD_ID

能否请您提出我该如何实现?

2 个答案:

答案 0 :(得分:3)

要将标量子查询转换为联接,您需要使用外部谓词而不是内部联接,并将相关谓词作为联接条件。

在您的情况下,这意味着查询将类似于:

SELECT clm.id,
     el.erac_actp_cd,
     clm.elct_id,
     clm.clmbt_id,
     COALESCE(clm.provider, pr.name) provider_name,
     cb.claim_type,
     el.account_no
FROM   election el
       INNER JOIN claim clm ON el.id = clm.elct_id
       INNER JOIN claim_batch cb ON clm.clmbt_id = cb.id
       LEFT OUTER JOIN provider pr ON clm.ee_id = pr.ee_id AND pr.id = clm.prvd_id
WHERE  clm.id = 1
AND    el.ee_id = 1;

我将您的DECODE变成了COALESCE,因为您想显示clm.provider(如果不为null)或pr.name(如果为null)。 COALESCE仅返回第一个非空值。

我也将查询转换为使用ANSI联接,而不是旧式联接;这样可以更清楚地了解什么是连接条件和什么是谓词。

答案 1 :(得分:2)

  

最初,我尝试使用内部联接使用以下查询。这不起作用,因为PRVD_ID可以为空。

您需要使用外部连接,使用ANSI语法要简单得多(尽管无论如何您都应该使用该连接);像这样:

SELECT CLM.ID,
  EL.ERAC_ACTP_CD,
  CLM.ELCT_ID,
  CLM.CLMBT_ID,
  DECODE(CLM.PROVIDER, NULL, PR.NAME, CLM.PROVIDER) PROVIDER_NAME,
  CB.CLAIM_TYPE,
  EL.ACCOUNT_NO
FROM ELECTION EL
JOIN CLAIM CLM ON CLM.ELCT_ID = EL.ID
JOIN CLAIM_BATCH CB ON CB.ID = CLM.CLMBT_ID
LEFT JOIN PROVIDER PR on PR.ID = CLM.PRVD_ID
WHERE CLM.ID = 1
AND EL.EE_ID = 1;

The

DECODE(CLM.PROVIDER, NULL, PR.NAME, CLM.PROVIDER)

也可以使用大小写表达式或nvl()coalesce()来完成:

COALESCE(CLM.PROVIDER, PR.NAME)

正如@Bonest所指出的那样,您可能需要包括一个附加条件,该条件出现在子查询中,但没有出现在您的联接尝试中:

LEFT JOIN PROVIDER PR on PR.ID = CLM.PRVD_ID
AND PR.EE_ID = CLM.EE_ID

但是不清楚是否故意遗漏了