SQL ORACLE DB 左连接的替代方法
Alternative way to left join in SQL ORACLE DB
如果我运行查询下面的查询:
SELECT day.M_CMP_TYPO AS M_CMP_TYPO,
day.M_SPTCV as M_SPTCV,
day.M_CNT_VS2 AS M_CNT_VS2,
day.M_CNT_ORG AS M_CNT_ORG,
day.M_PL_CGR2 AS M_PL_CGR2,
day.M_PL_CGU2 AS M_PL_CGU2,
day.M_PL_CSFI2 AS M_PL_CSFI2,
day.M_PL_FTFI2 AS M_PL_FTFI2,
day.M_PL_RVR2 AS M_PL_RVR2,
day.M_PL_RVU2 AS M_PL_RVU2,
day.M_TRN_FMLY AS M_TRN_FMLY,
day.M_TRN_GRP AS M_TRN_GRP,
day.M_TRN_TYPE AS M_TRN_TYPE,
day.M_CNT_VS2 AS M_CNT_VS2,
day.M_C_CUR_PL AS M_C_CUR_PL,
day.M_INSTRLABEL AS M_INSTRLABEL,
day.M_NB AS M_NB,
day.M_PL_INSCUR AS M_PL_INSCUR,
day.M_TP_CNTRPLB AS M_TP_CNTRPLB,
day.M_TP_PFOLIO AS M_TP_PFOLIO,
day.M_ECO_PL AS M_ECO_PL,
day.M_CNT_ID AS M_CNT_ID,
day.M_ECO_PL_USD AS M_ECO_PL_USD,
day.M_POS_CURR2 AS M_POS_CURR2,
day.M_CURR2 AS M_CURR2,
day.M_TP_QTYEQ AS M_TP_QTYEQ,
day.M_TP_UQTYEQ AS M_TP_UQTYEQ,
day.M_TP_LQTY32 AS M_TP_LQTY32,
day.M_TP_UQTY AS M_TP_UQTY,
--day.M_ECO_PL - daily.M_ECO_PL AS DAILY_VAR,
--day.M_ECO_PL - month.M_ECO_PL AS MTD,
day.M_ECO_PL - year.M_ECO_PL AS YTD,
--day.M_SPTCV * (day.M_ECO_PL - daily.M_ECO_PL) as DAILY_VAR_USD,
--day.M_SPTCV * (day.M_ECO_PL - month.M_ECO_PL) as MTD_USD,
day.M_SPTCV * (day.M_ECO_PL - year.M_ECO_PL) as YTD_USD
FROM RT_PLVAR_REP day
LEFT JOIN RT_PLVAR_REP year ON day.M_NB = year.M_NB
--LEFT JOIN RT_PLVAR_REP month ON day.M_NB = month.M_NB
--LEFT JOIN RT_PLVAR_REP daily ON day.M_NB = daily.M_NB
WHERE day.M_REF_DATA = 18
AND year.M_REF_DATA = 20
--AND month.M_REF_DATA = 0
--AND daily.M_REF_DATA = 0
它 return 是预期的行为,这意味着它 return 27 行知道 year.M_REF_DATA = 20 存在于数据库中。否则如果我 运行 这个我没有价值。
由于 M_REF_DATA=0 在 table 中不存在,我期望此查询 returns 27 行,但相关列应该 return 为空,但这不是案例.
我试过将 Where 替换为 AND 它也没有用。它 returned 1728 行,这是一个错误的答案,它应该 return 11. 我的问题是为什么左连接没有像我期望的那样工作?
SELECT day.M_CMP_TYPO AS M_CMP_TYPO,
day.M_SPTCV as M_SPTCV,
day.M_CNT_VS2 AS M_CNT_VS2,
day.M_CNT_ORG AS M_CNT_ORG,
day.M_PL_CGR2 AS M_PL_CGR2,
day.M_PL_CGU2 AS M_PL_CGU2,
day.M_PL_CSFI2 AS M_PL_CSFI2,
day.M_PL_FTFI2 AS M_PL_FTFI2,
day.M_PL_RVR2 AS M_PL_RVR2,
day.M_PL_RVU2 AS M_PL_RVU2,
day.M_TRN_FMLY AS M_TRN_FMLY,
day.M_TRN_GRP AS M_TRN_GRP,
day.M_TRN_TYPE AS M_TRN_TYPE,
day.M_CNT_VS2 AS M_CNT_VS2,
day.M_C_CUR_PL AS M_C_CUR_PL,
day.M_INSTRLABEL AS M_INSTRLABEL,
day.M_NB AS M_NB,
day.M_PL_INSCUR AS M_PL_INSCUR,
day.M_TP_CNTRPLB AS M_TP_CNTRPLB,
day.M_TP_PFOLIO AS M_TP_PFOLIO,
day.M_ECO_PL AS M_ECO_PL,
day.M_CNT_ID AS M_CNT_ID,
day.M_ECO_PL_USD AS M_ECO_PL_USD,
day.M_POS_CURR2 AS M_POS_CURR2,
day.M_CURR2 AS M_CURR2,
day.M_TP_QTYEQ AS M_TP_QTYEQ,
day.M_TP_UQTYEQ AS M_TP_UQTYEQ,
day.M_TP_LQTY32 AS M_TP_LQTY32,
day.M_TP_UQTY AS M_TP_UQTY,
day.M_ECO_PL - daily.M_ECO_PL AS DAILY_VAR,
day.M_ECO_PL - month.M_ECO_PL AS MTD,
day.M_ECO_PL - year.M_ECO_PL AS YTD,
day.M_SPTCV * (day.M_ECO_PL - daily.M_ECO_PL) as DAILY_VAR_USD,
day.M_SPTCV * (day.M_ECO_PL - month.M_ECO_PL) as MTD_USD,
day.M_SPTCV * (day.M_ECO_PL - year.M_ECO_PL) as YTD_USD
FROM RT_PLVAR_REP day
LEFT JOIN RT_PLVAR_REP year ON day.M_NB = year.M_NB
LEFT JOIN RT_PLVAR_REP month ON day.M_NB = month.M_NB
LEFT JOIN RT_PLVAR_REP daily ON day.M_NB = daily.M_NB
WHERE day.M_REF_DATA = 18
AND year.M_REF_DATA = 0
AND month.M_REF_DATA = 0
AND daily.M_REF_DATA = 0
这是第一个查询中的 from
和 where
子句:
FROM RT_PLVAR_REP day LEFT JOIN
RT_PLVAR_REP year
ON day.M_NB = year.M_NB
WHERE day.M_REF_DATA = 18 AND year.M_REF_DATA = 20
where
子句将 LEFT JOIN
转换为 INNER JOIN
。 year.M_REF_DATA
的值为 NULL,因此不符合条件。
对于 LEFT JOIN
,条件应该放在 ON
子句中:
FROM RT_PLVAR_REP day LEFT JOIN
RT_PLVAR_REP year
ON day.M_NB = year.M_NB AND year.M_REF_DATA = 20
WHERE day.M_REF_DATA = 18
第一个table的条件应该留在WHERE
。
对于外部联接,您需要将筛选条件移动到联接:
FROM RT_PLVAR_REP day
LEFT JOIN RT_PLVAR_REP year
ON day.M_NB = year.M_NB
AND year.M_REF_DATA = 0
LEFT JOIN RT_PLVAR_REP month
ON day.M_NB = month.M_NB
AND month.M_REF_DATA = 0
LEFT JOIN RT_PLVAR_REP daily
ON day.M_NB = daily.M_NB
AND daily.M_REF_DATA = 0
WHERE day.M_REF_DATA = 18
这告诉数据库您只想在存在行时强制执行该条件。
如果我运行查询下面的查询:
SELECT day.M_CMP_TYPO AS M_CMP_TYPO,
day.M_SPTCV as M_SPTCV,
day.M_CNT_VS2 AS M_CNT_VS2,
day.M_CNT_ORG AS M_CNT_ORG,
day.M_PL_CGR2 AS M_PL_CGR2,
day.M_PL_CGU2 AS M_PL_CGU2,
day.M_PL_CSFI2 AS M_PL_CSFI2,
day.M_PL_FTFI2 AS M_PL_FTFI2,
day.M_PL_RVR2 AS M_PL_RVR2,
day.M_PL_RVU2 AS M_PL_RVU2,
day.M_TRN_FMLY AS M_TRN_FMLY,
day.M_TRN_GRP AS M_TRN_GRP,
day.M_TRN_TYPE AS M_TRN_TYPE,
day.M_CNT_VS2 AS M_CNT_VS2,
day.M_C_CUR_PL AS M_C_CUR_PL,
day.M_INSTRLABEL AS M_INSTRLABEL,
day.M_NB AS M_NB,
day.M_PL_INSCUR AS M_PL_INSCUR,
day.M_TP_CNTRPLB AS M_TP_CNTRPLB,
day.M_TP_PFOLIO AS M_TP_PFOLIO,
day.M_ECO_PL AS M_ECO_PL,
day.M_CNT_ID AS M_CNT_ID,
day.M_ECO_PL_USD AS M_ECO_PL_USD,
day.M_POS_CURR2 AS M_POS_CURR2,
day.M_CURR2 AS M_CURR2,
day.M_TP_QTYEQ AS M_TP_QTYEQ,
day.M_TP_UQTYEQ AS M_TP_UQTYEQ,
day.M_TP_LQTY32 AS M_TP_LQTY32,
day.M_TP_UQTY AS M_TP_UQTY,
--day.M_ECO_PL - daily.M_ECO_PL AS DAILY_VAR,
--day.M_ECO_PL - month.M_ECO_PL AS MTD,
day.M_ECO_PL - year.M_ECO_PL AS YTD,
--day.M_SPTCV * (day.M_ECO_PL - daily.M_ECO_PL) as DAILY_VAR_USD,
--day.M_SPTCV * (day.M_ECO_PL - month.M_ECO_PL) as MTD_USD,
day.M_SPTCV * (day.M_ECO_PL - year.M_ECO_PL) as YTD_USD
FROM RT_PLVAR_REP day
LEFT JOIN RT_PLVAR_REP year ON day.M_NB = year.M_NB
--LEFT JOIN RT_PLVAR_REP month ON day.M_NB = month.M_NB
--LEFT JOIN RT_PLVAR_REP daily ON day.M_NB = daily.M_NB
WHERE day.M_REF_DATA = 18
AND year.M_REF_DATA = 20
--AND month.M_REF_DATA = 0
--AND daily.M_REF_DATA = 0
它 return 是预期的行为,这意味着它 return 27 行知道 year.M_REF_DATA = 20 存在于数据库中。否则如果我 运行 这个我没有价值。 由于 M_REF_DATA=0 在 table 中不存在,我期望此查询 returns 27 行,但相关列应该 return 为空,但这不是案例.
我试过将 Where 替换为 AND 它也没有用。它 returned 1728 行,这是一个错误的答案,它应该 return 11. 我的问题是为什么左连接没有像我期望的那样工作?
SELECT day.M_CMP_TYPO AS M_CMP_TYPO,
day.M_SPTCV as M_SPTCV,
day.M_CNT_VS2 AS M_CNT_VS2,
day.M_CNT_ORG AS M_CNT_ORG,
day.M_PL_CGR2 AS M_PL_CGR2,
day.M_PL_CGU2 AS M_PL_CGU2,
day.M_PL_CSFI2 AS M_PL_CSFI2,
day.M_PL_FTFI2 AS M_PL_FTFI2,
day.M_PL_RVR2 AS M_PL_RVR2,
day.M_PL_RVU2 AS M_PL_RVU2,
day.M_TRN_FMLY AS M_TRN_FMLY,
day.M_TRN_GRP AS M_TRN_GRP,
day.M_TRN_TYPE AS M_TRN_TYPE,
day.M_CNT_VS2 AS M_CNT_VS2,
day.M_C_CUR_PL AS M_C_CUR_PL,
day.M_INSTRLABEL AS M_INSTRLABEL,
day.M_NB AS M_NB,
day.M_PL_INSCUR AS M_PL_INSCUR,
day.M_TP_CNTRPLB AS M_TP_CNTRPLB,
day.M_TP_PFOLIO AS M_TP_PFOLIO,
day.M_ECO_PL AS M_ECO_PL,
day.M_CNT_ID AS M_CNT_ID,
day.M_ECO_PL_USD AS M_ECO_PL_USD,
day.M_POS_CURR2 AS M_POS_CURR2,
day.M_CURR2 AS M_CURR2,
day.M_TP_QTYEQ AS M_TP_QTYEQ,
day.M_TP_UQTYEQ AS M_TP_UQTYEQ,
day.M_TP_LQTY32 AS M_TP_LQTY32,
day.M_TP_UQTY AS M_TP_UQTY,
day.M_ECO_PL - daily.M_ECO_PL AS DAILY_VAR,
day.M_ECO_PL - month.M_ECO_PL AS MTD,
day.M_ECO_PL - year.M_ECO_PL AS YTD,
day.M_SPTCV * (day.M_ECO_PL - daily.M_ECO_PL) as DAILY_VAR_USD,
day.M_SPTCV * (day.M_ECO_PL - month.M_ECO_PL) as MTD_USD,
day.M_SPTCV * (day.M_ECO_PL - year.M_ECO_PL) as YTD_USD
FROM RT_PLVAR_REP day
LEFT JOIN RT_PLVAR_REP year ON day.M_NB = year.M_NB
LEFT JOIN RT_PLVAR_REP month ON day.M_NB = month.M_NB
LEFT JOIN RT_PLVAR_REP daily ON day.M_NB = daily.M_NB
WHERE day.M_REF_DATA = 18
AND year.M_REF_DATA = 0
AND month.M_REF_DATA = 0
AND daily.M_REF_DATA = 0
这是第一个查询中的 from
和 where
子句:
FROM RT_PLVAR_REP day LEFT JOIN
RT_PLVAR_REP year
ON day.M_NB = year.M_NB
WHERE day.M_REF_DATA = 18 AND year.M_REF_DATA = 20
where
子句将 LEFT JOIN
转换为 INNER JOIN
。 year.M_REF_DATA
的值为 NULL,因此不符合条件。
对于 LEFT JOIN
,条件应该放在 ON
子句中:
FROM RT_PLVAR_REP day LEFT JOIN
RT_PLVAR_REP year
ON day.M_NB = year.M_NB AND year.M_REF_DATA = 20
WHERE day.M_REF_DATA = 18
第一个table的条件应该留在WHERE
。
对于外部联接,您需要将筛选条件移动到联接:
FROM RT_PLVAR_REP day
LEFT JOIN RT_PLVAR_REP year
ON day.M_NB = year.M_NB
AND year.M_REF_DATA = 0
LEFT JOIN RT_PLVAR_REP month
ON day.M_NB = month.M_NB
AND month.M_REF_DATA = 0
LEFT JOIN RT_PLVAR_REP daily
ON day.M_NB = daily.M_NB
AND daily.M_REF_DATA = 0
WHERE day.M_REF_DATA = 18
这告诉数据库您只想在存在行时强制执行该条件。