【问题标题】:Changing SUBQUERY in WHERE clause to NORMAL JOIN将 WHERE 子句中的 SUBQUERY 更改为 NORMAL JOIN
【发布时间】:2017-06-29 04:47:43
【问题描述】:

我的新系统不接受嵌套/子查询。我需要帮助将下面的 sql 转换为普通连接。我尝试了我的方法,但结果不一样:

SELECT
*
FROM
TRAINING.COURSE_SCHEDULE COURSE_SCHEDULE
LEFT JOIN
ENGINE.PHASE_SETTINGS PHASE_SETTINGS ON (COURSE_SCHEDULE.ETQ$CURRENT_PHASE = PHASE_SETTINGS.PHASE_ID)
LEFT JOIN
TRAINING.COURSE_PROFILE AS COURSE_PROFILE ON (COURSE_SCHEDULE.COURSE_PROFILE = COURSE_PROFILE.COURSE_PROFILE_ID)
LEFT JOIN
TRAINING.ETQ$COURSE_SCHEDULE_ASN ETQ$COURSE_SCHEDULE_ASN_1 ON (COURSE_SCHEDULE.COURSE_SCHEDULE_ID = ETQ$COURSE_SCHEDULE_ASN_1.COURSE_SCHEDULE_ID)
LEFT JOIN
ENGINE.USER_SETTINGS USER_SETTINGS_1 ON (ETQ$COURSE_SCHEDULE_ASN_1.ETQ$ASSIGNED = USER_SETTINGS_1.USER_ID)
LEFT JOIN
ENGINE.BOOLEAN_VALUES BOOLEAN_VALUES_1 ON (COURSE_SCHEDULE.TEST_IS_REQUIRED = BOOLEAN_VALUES_1.VALUE)
WHERE
PHASE_SETTINGS.PHASE_TYPE IN (5)
AND COURSE_PROFILE.COURSE_PROFILE_ID NOT IN


(SELECT COURSE_PROFILE.COURSE_PROFILE_ID
FROM TRAINING.COURSE_PROFILE COURSE_PROFILE
LEFT JOIN
TRAINING.ETQ$COURSE_PROFILE_TTL TEST_TEMPLATE_LINK ON (COURSE_PROFILE.COURSE_PROFILE_ID = TEST_TEMPLATE_LINK.COURSE_PROFILE_ID)
LEFT JOIN
TRAINING.ETQ$DOCUMENT_LINKS DOCUMENT_LINKS ON (TEST_TEMPLATE_LINK.TEST_TEMPLATE_ID = DOCUMENT_LINKS.LINK_ID)
LEFT JOIN
TRAINING.TEST_TEMPLATE ON (DOCUMENT_LINKS.DOCUMENT_ID = TEST_TEMPLATE.TEST_TEMPLATE_ID)
LEFT JOIN
TRAINING.TEST_DOCUMENT TEST_DOCUMENT ON (TEST_TEMPLATE.TEST_TEMPLATE_ID = TEST_DOCUMENT.TEST_TEMPLATE)
WHERE TEST_DOCUMENT_DATE IS NULL)

【问题讨论】:

  • 当您说“我的新系统不接受嵌套/子查询”时,这是什么意思?你有错误吗?还是这是一个政治问题而不是技术问题?
  • 另外,由于我们不了解业务规则、数据和访问路径,我们很难重写其他人的查询。
  • 这是 Oracle 还是 MySQL?它们不一样,语法也不同。请正确标记
  • test_document_date 属于哪个表?即在您使用WHERE test_document_date IS NULL 的子查询中,但没有任何内容表明它属于哪个表。您可以尝试更改 where 子句以使用 NOT EXISTS 而不是 NOT IN
  • 请扶好你的马。这更像是一种政治局势 :) 我不是要求重写,只是给我一个方法,以便我可以工作。

标签: mysql sql subquery left-join


【解决方案1】:

With 子句算嵌套吗?

WITH UNWANTED AS(
    SELECT COURSE_PROFILE.COURSE_PROFILE_ID
    FROM TRAINING.COURSE_PROFILE COURSE_PROFILE
    LEFT JOIN TRAINING.ETQ$COURSE_PROFILE_TTL TEST_TEMPLATE_LINK ON (COURSE_PROFILE.COURSE_PROFILE_ID = TEST_TEMPLATE_LINK.COURSE_PROFILE_ID)
    LEFT JOIN TRAINING.ETQ$DOCUMENT_LINKS DOCUMENT_LINKS ON (TEST_TEMPLATE_LINK.TEST_TEMPLATE_ID = DOCUMENT_LINKS.LINK_ID)
    LEFT JOIN TRAINING.TEST_TEMPLATE ON (DOCUMENT_LINKS.DOCUMENT_ID = TEST_TEMPLATE.TEST_TEMPLATE_ID)
    LEFT JOIN TRAINING.TEST_DOCUMENT TEST_DOCUMENT ON (TEST_TEMPLATE.TEST_TEMPLATE_ID = TEST_DOCUMENT.TEST_TEMPLATE)
    WHERE TEST_DOCUMENT_DATE IS NULL
)
SELECT *
FROM TRAINING.COURSE_SCHEDULE COURSE_SCHEDULE
LEFT JOIN ENGINE.PHASE_SETTINGS PHASE_SETTINGS ON (COURSE_SCHEDULE.ETQ$CURRENT_PHASE = PHASE_SETTINGS.PHASE_ID)
LEFT JOIN TRAINING.COURSE_PROFILE AS COURSE_PROFILE ON (COURSE_SCHEDULE.COURSE_PROFILE = COURSE_PROFILE.COURSE_PROFILE_ID)
LEFT JOIN TRAINING.ETQ$COURSE_SCHEDULE_ASN ETQ$COURSE_SCHEDULE_ASN_1 ON (COURSE_SCHEDULE.COURSE_SCHEDULE_ID = ETQ$COURSE_SCHEDULE_ASN_1.COURSE_SCHEDULE_ID)
LEFT JOIN ENGINE.USER_SETTINGS USER_SETTINGS_1 ON (ETQ$COURSE_SCHEDULE_ASN_1.ETQ$ASSIGNED = USER_SETTINGS_1.USER_ID)
LEFT JOIN ENGINE.BOOLEAN_VALUES BOOLEAN_VALUES_1 ON (COURSE_SCHEDULE.TEST_IS_REQUIRED = BOOLEAN_VALUES_1.VALUE)
LEFT JOIN UNWANTED UNW on UNW.COURSE_PROFILE_ID = COURSE_PROFILE.COURSE_PROFILE_ID
WHERE PHASE_SETTINGS.PHASE_TYPE IN (5)
AND UNW.COURSE_PROFILE_ID IS NULL;

我知道WITH 是嵌套子查询的一种变通选项,如果这对您的痛苦限制没有帮助,我很抱歉。

更新:

好的,让我们尝试这种方式,基本上应用与上述相同的逻辑,但子查询现在与您的主要SELECT 集成,我相信这就是您首先要寻找的:

SELECT *
FROM TRAINING.COURSE_SCHEDULE AS COURSE_SCHEDULE
LEFT JOIN ENGINE.PHASE_SETTINGS AS PHASE_SETTINGS ON (COURSE_SCHEDULE.ETQ$CURRENT_PHASE = PHASE_SETTINGS.PHASE_ID)
LEFT JOIN TRAINING.COURSE_PROFILE AS COURSE_PROFILE ON (COURSE_SCHEDULE.COURSE_PROFILE = COURSE_PROFILE.COURSE_PROFILE_ID)
LEFT JOIN TRAINING.ETQ$COURSE_SCHEDULE_ASN AS ETQ$COURSE_SCHEDULE_ASN_1 ON (COURSE_SCHEDULE.COURSE_SCHEDULE_ID = ETQ$COURSE_SCHEDULE_ASN_1.COURSE_SCHEDULE_ID)
LEFT JOIN ENGINE.USER_SETTINGS AS USER_SETTINGS_1 ON (ETQ$COURSE_SCHEDULE_ASN_1.ETQ$ASSIGNED = USER_SETTINGS_1.USER_ID)
LEFT JOIN ENGINE.BOOLEAN_VALUES AS BOOLEAN_VALUES_1 ON (COURSE_SCHEDULE.TEST_IS_REQUIRED = BOOLEAN_VALUES_1.VALUE)
LEFT JOIN TRAINING.COURSE_PROFILE AS COURSE_PROFILE_2 ON COURSE_PROFILE_2.COURSE_PROFILE_ID = COURSE_PROFILE.COURSE_PROFILE_ID
LEFT JOIN TRAINING.ETQ$COURSE_PROFILE_TTL AS TEST_TEMPLATE_LINK ON (COURSE_PROFILE_2.COURSE_PROFILE_ID = TEST_TEMPLATE_LINK.COURSE_PROFILE_ID)
LEFT JOIN TRAINING.ETQ$DOCUMENT_LINKS AS DOCUMENT_LINKS ON (TEST_TEMPLATE_LINK.TEST_TEMPLATE_ID = DOCUMENT_LINKS.LINK_ID)
LEFT JOIN TRAINING.TEST_TEMPLATE ON (DOCUMENT_LINKS.DOCUMENT_ID = TEST_TEMPLATE.TEST_TEMPLATE_ID)
LEFT JOIN TRAINING.TEST_DOCUMENT AS TEST_DOCUMENT ON (TEST_TEMPLATE.TEST_TEMPLATE_ID = TEST_DOCUMENT.TEST_TEMPLATE
                                                      AND TEST_DOCUMENT.TEST_DOCUMENT_DATE IS NULL)
WHERE PHASE_SETTINGS.PHASE_TYPE IN (5)
AND COURSE_PROFILE_2.COURSE_PROFILE_ID IS NULL;

请注意,我将 COURSE_PROFILE 的别名从原始嵌套查询更改为 COURSE_PROFILE_2,因此它不会与主查询中的 COURSE_PROFILE 冲突,并且由于原始子查询中的列 TEST_DOCUMENT_DATE 没有附加了一个表别名,我从它的名称推断它属于TEST_DOCUMENT 表,如果这是错误的,请更改它。祝你好运。

【讨论】:

  • 这真的很棒。请给我一点时间试试这个:)
  • 不幸的是,与同一 SQL 中的两个 SELECT 语句相同的错误被拒绝,再次感谢您的检查
  • 好的,没问题,我已经更新了我的答案以尝试一种新的方法,如果你愿意,请检查一下。
  • 再次感谢...为什么最后将 ID 添加为 NULL? AND COURSE_PROFILE_2.COURSE_PROFILE_ID 为空
  • 在原始查询中,您想要子查询返回的所有 COURSE_PROFILE_ID NOT INCOURSE_PROFILE_ID。使用这种方法,由子查询建立的所有LEFT JOINED 表现在都集成到主查询中,将为您提供与COURSE_PROFILE_ID 匹配的所有行,但也提供不匹配的行,这就是@987654336 @ 出现,所有显示为 NULL 的 ID 都是子查询逻辑中不存在的 ID,因此排除这些行将提供与原始 NOT IN 中相同的结果
猜你喜欢
  • 1970-01-01
  • 2016-11-30
  • 1970-01-01
  • 2016-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多