Sql 使用联接转换内联查询

Sql 使用联接转换内联查询,sql,oracle,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

我正在尝试替换现有的内联查询,并使用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\u ID列值可以为空。

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

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
你能建议我如何做到这一点吗

最初,我尝试使用内部联接使用下面的查询。这不起作用,因为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;
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;

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

正如@Bonest所指出的,您可能需要包含一个附加条件,该条件存在于子查询中,但不存在于您的加入尝试中:

LEFT JOIN PROVIDER PR on PR.ID = CLM.PRVD_ID
AND PR.EE_ID = CLM.EE_ID
但不清楚你是不是故意漏掉了

最初,我尝试使用内部联接使用下面的查询。这不起作用,因为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;
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;

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

正如@Bonest所指出的,您可能需要包含一个附加条件,该条件存在于子查询中,但不存在于您的加入尝试中:

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

但是不清楚您是否故意忽略了这一点。

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

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

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;
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;
注意,我已经将您的解码转换为合并,因为您希望显示clm.provider(如果不为null)或pr.name(如果为null)。COALESCE只返回第一个非空值


我还将您的查询转换为使用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;
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;
注意,我已经将您的解码转换为合并,因为您希望显示clm.provider(如果不为null)或pr.name(如果为null)。COALESCE只返回第一个非空值


我还将您的查询转换为使用ANSI连接,而不是旧式连接;这使我们更清楚地了解什么是连接条件,什么是谓词。

您的代码、示例数据和所需的结果将非常有用。此外,更好地切换到ANSI连接语法。得到的结果与实际结果不同。。。有什么区别?这里只有一个查询。请显示您的加入尝试。还包括您当前的加入尝试、获得的结果以及错误原因。请编辑问题,以将所有信息添加为格式化文本,不要试图将其放入注释中。您的代码、示例数据和所需结果将非常有用。此外,更好地切换到ANSI连接语法。得到的结果与实际结果不同。。。有什么区别?这里只有一个查询。请显示您的加入尝试。还包括您当前的加入尝试、获得的结果以及错误原因。请编辑问题以将所有信息添加为格式化文本,不要试图把它放在注释中。
尽管你无论如何都应该使用它来强调。
尽管你无论如何都应该使用它来强调。
尽管你无论如何都应该使用它来强调。
>>也要注意,
clm.id=1
可以包含在
内部连接声明clm ON….
中。由于它是一个
内部联接
,因此不应更改结果,并将使
联接
更高效。尽管优化器可能已经在幕后完成了这项工作。这些事情正在变得相当聪明。:-)还要注意,
clm.id=1
可以包含在..
上的
内部连接声明clm中。由于它是一个
内部联接
,因此不应更改结果,并将使
联接
更高效。尽管优化器可能已经在幕后完成了这项工作。这些事情正在变得相当聪明。:-)