在查询中避免使用IN

时间:2014-11-20 17:21:25

标签: sql sql-server

我有桌子

M,R,G,D,PT和PI

PI与所有其他表格有关系。 存在M,R,G和D的亲子关系。

示例:模型ID将出现在M和R中           范围ID将在R和G中           等级ID将出现在G和D

要知道发布的衍生物,示例如下

 SELECT D.DERIVATIVE_ID
 FROM   PRD.DERIVATIVE D
        JOIN PUB.PUBLISHED_ITEM PI ON PI.PUBLISHED_OBJECT_ID = D.DERIVATIVE_ID
                                      AND PI.PUBLISHED_OBJECT_TYPE = 'DERIVATIVE'
        JOIN PUB.PUBLISHED_TARGET PT ON PI.PUBLISHED_TARGET_ID = PT.PUBLISHED_TARGET_ID
 WHERE  D.DERIVATIVE_ID = 683239

要了解已发布的模型,示例如下

SELECT  *
FROM    PRD.MODEL M
        JOIN PUB.PUBLISHED_ITEM PI ON PI.PUBLISHED_OBJECT_ID = M.MODEL_ID
                                      AND PI.PUBLISHED_OBJECT_TYPE = 'MODEL'
        JOIN PUB.PUBLISHED_TARGET PT ON PI.PUBLISHED_TARGET_ID = PT.PUBLISHED_TARGET_ID
WHERE   M.model_id = 257

我想写一个查询来显示模型,其衍生出版但不是模型(模型未公布)

以下是我尝试的内容,您的反馈会有所帮助

SELECT  *
FROM    PRD.MODEL M
        JOIN PUB.PUBLISHED_ITEM PI ON PI.PUBLISHED_OBJECT_ID = M.MODEL_ID
                                      AND PI.PUBLISHED_OBJECT_TYPE = 'MODEL'
        JOIN PUB.PUBLISHED_TARGET PT ON PI.PUBLISHED_TARGET_ID <> PT.PUBLISHED_TARGET_ID
        JOIN PRD.RANGE R ON R.MODEL_ID = M.MODEL_ID
        JOIN PRD.GRADE G ON G.RANGE_ID = R.RANGE_ID
        JOIN prd.DERIVATIVE D ON D.GRADE_ID = G.GRADE_ID
                                 AND D.DERIVATIVE_ID IN (
                                 SELECT D.DERIVATIVE_ID
                                 FROM   PRD.DERIVATIVE D
                                        JOIN PUB.PUBLISHED_ITEM PI ON PI.PUBLISHED_OBJECT_ID = D.DERIVATIVE_ID
                                                              AND PI.PUBLISHED_OBJECT_TYPE = 'DERIVATIVE'
                                        JOIN PUB.PUBLISHED_TARGET PT ON PI.PUBLISHED_TARGET_ID = PT.PUBLISHED_TARGET_ID )

同样在上述查询中,如何避免使用“IN”?

2 个答案:

答案 0 :(得分:0)

使用INNER Join可以避免。

SELECT *
FROM   PRD.MODEL M
       JOIN PUB.PUBLISHED_ITEM PI
         ON PI.PUBLISHED_OBJECT_ID = M.MODEL_ID
            AND PI.PUBLISHED_OBJECT_TYPE = 'MODEL'
       JOIN PUB.PUBLISHED_TARGET PT
         ON PI.PUBLISHED_TARGET_ID <> PT.PUBLISHED_TARGET_ID
       JOIN PRD.RANGE R
         ON R.MODEL_ID = M.MODEL_ID
       JOIN PRD.GRADE G
         ON G.RANGE_ID = R.RANGE_ID
       JOIN prd.DERIVATIVE d
         ON d.GRADE_ID = g.GRADE_ID
       JOIN (SELECT DISTINCT D.DERIVATIVE_ID
             FROM   PRD.DERIVATIVE D
                    JOIN PUB.PUBLISHED_ITEM PI
                      ON PI.PUBLISHED_OBJECT_ID = D.DERIVATIVE_ID
                         AND PI.PUBLISHED_OBJECT_TYPE = 'DERIVATIVE'
                    JOIN PUB.PUBLISHED_TARGET PT
                      ON PI.PUBLISHED_TARGET_ID = PT.PUBLISHED_TARGET_ID) AA
         ON D.DERIVATIVE_ID = AA.DERIVATIVE_ID 

使用Exists

SELECT *
FROM   PRD.MODEL M
       JOIN PUB.PUBLISHED_ITEM PI
         ON PI.PUBLISHED_OBJECT_ID = M.MODEL_ID
            AND PI.PUBLISHED_OBJECT_TYPE = 'MODEL'
       JOIN PUB.PUBLISHED_TARGET PT
         ON PI.PUBLISHED_TARGET_ID <> PT.PUBLISHED_TARGET_ID
       JOIN PRD.RANGE R
         ON R.MODEL_ID = M.MODEL_ID
       JOIN PRD.GRADE G
         ON G.RANGE_ID = R.RANGE_ID
       JOIN prd.DERIVATIVE D
         ON D.GRADE_ID = G.GRADE_ID
WHERE  EXISTS (SELECT 'X'
               FROM   PRD.DERIVATIVE ED
                      JOIN PUB.PUBLISHED_ITEM EPI
                        ON EPI.PUBLISHED_OBJECT_ID = ED.DERIVATIVE_ID
                           AND EPI.PUBLISHED_OBJECT_TYPE = 'DERIVATIVE'
                      JOIN PUB.PUBLISHED_TARGET EPT
                        ON EPI.PUBLISHED_TARGET_ID = EPT.PUBLISHED_TARGET_ID
               WHERE  ED.DERIVATIVE_ID = D.DERIVATIVE_ID) 

答案 1 :(得分:0)

常用方法是EXISTS

SELECT *
FROM PRD.MODEL M
JOIN PUB.PUBLISHED_ITEM PI
    ON PI.PUBLISHED_OBJECT_ID = M.MODEL_ID
        AND PI.PUBLISHED_OBJECT_TYPE = 'MODEL'
JOIN PUB.PUBLISHED_TARGET PT
    ON PI.PUBLISHED_TARGET_ID <> PT.PUBLISHED_TARGET_ID
JOIN PRD.RANGE R
    ON R.MODEL_ID = M.MODEL_ID
JOIN PRD.GRADE G
    ON G.RANGE_ID = R.RANGE_ID
JOIN prd.DERIVATIVE D
    ON D.GRADE_ID = G.GRADE_ID
WHERE EXISTS (
        SELECT 1
        FROM PRD.DERIVATIVE D_s
        JOIN PUB.PUBLISHED_ITEM PI_s
            ON  PI_s.PUBLISHED_OBJECT_ID = D_S.DERIVATIVE_ID
            AND PI_s.PUBLISHED_OBJECT_TYPE = 'DERIVATIVE'
        JOIN PUB.PUBLISHED_TARGET PT_s
            ON PI_s.PUBLISHED_TARGET_ID = PT_s.PUBLISHED_TARGET_ID
        WHERE D_s.DERIVATIVE_ID =  D.DERIVATIVE_ID
        )