2014-09-13 62 views
0

我有一个很大的查询,相当大。即使我指定了“DISTINCT”,该查询也会在MATERIAL列上不断生成多个结果。我想通过指定'DISTINCT'并将我需要的值相加,以便每个材料编号产生一行。任何人都可以帮助我看到我在这里做错了什么。我意识到最后的子查询在这一点上可能是多余的 - 我正在测试,这正是我得到的结果。根据SELECT字段中的一个值在大型查询中选择最近的记录

提前致谢。

DECLARE @daynumber as int 
SET  @daynumber = CASE 
        WHEN DATENAME(dw,GETDATE()) = 'Monday' 
        THEN 56 
        WHEN DATENAME(dw,GETDATE()) = 'Tuesday' 
        THEN 57 
        WHEN DATENAME(dw,GETDATE()) = 'Wednesday' 
        THEN 58 
        WHEN DATENAME(dw,GETDATE()) = 'Thursday' 
        THEN 59 
        WHEN DATENAME(dw,GETDATE()) = 'Friday' 
        THEN 60 
        END; 

SELECT   DISTINCT MATERIAL, 
       PLANT_CODE, 
       STOCK_CATEGORY, 
       material_desc AS 'MATERIAL_DESC', 
       division_id AS 'DIVISION_ID', 
       UPPER(division_desc) AS 'DIVISION_DESC', 
       UPPER(gender_id) AS 'GENDER_ID', 
       UPPER(gender_desc) AS 'GENDER_DESC', 
       DISTRIBUTION_VERSION_CODE, 
       PERIOD_CODE, 
       REQUIREMENTS_DATE, 
       VERSION_IND_FLAG, 
       TECHNICAL_INDEX, 
       SIZE_LITERAL, 
       [ORIGINAL FCST QTY], 
       WITHDRAWN_QUANTITY, 
       [REM PLAN QTY], 
       FUTURE_FCST, 
       TOTAL_OH_INV 
FROM (

SELECT   P1.PLANT_CODE, 
       P1.STOCK_CATEGORY, 
       P1.MATERIAL, 
       M1.material_desc AS 'MATERIAL_DESC', 
       M1.division_id AS 'DIVISION_ID', 
       UPPER(M1.division_desc) AS 'DIVISION_DESC', 
       UPPER(M1.gender_id) AS 'GENDER_ID', 
       UPPER(M1.gender_desc) AS 'GENDER_DESC', 
       P1.DISTRIBUTION_VERSION_CODE, 
       P1.PERIOD_CODE, 
       P1.REQUIREMENTS_DATE, 
       P1.VERSION_IND_FLAG, 
       P1.TECHNICAL_INDEX, 
       P1.SIZE_LITERAL, 
       P1.[ORIGINAL FCST QTY], 
       P1.WITHDRAWN_QUANTITY, 
       P1.[REM PLAN QTY], 
       P2.FUTURE_FCST, 
       SUM(I1.ON_HAND_QUANTITY) AS 'TOTAL_OH_INV' 
FROM 

(SELECT   PLANT_CODE, 
       STOCK_CATEGORY, 
       MATERIAL, 
       DISTRIBUTION_VERSION_CODE, 
       PERIOD_CODE, 
       REQUIREMENTS_DATE, 
       PLANNED_QTY AS 'REM PLAN QTY', 
       VERSION_IND_FLAG, 
       SIZE_LITERAL, 
       WITHDRAWN_QUANTITY, 
       TECHNICAL_INDEX, 
       PLANNED_QTY + WITHDRAWN_QUANTITY AS 'ORIGINAL FCST QTY' 
FROM   VW_PLANNED_REQMNTS_TXT 
WHERE   PLANT_CODE IN ('6040','6041') 
AND   STOCK_CATEGORY IN ('A60385000','A60385003') 
AND   DISTRIBUTION_VERSION_CODE IN ('00','01','ZU','Z2') 
AND   REQUIREMENTS_DATE < GETDATE() - @daynumber 
AND   PLANNED_QTY > 0) AS P1 

LEFT OUTER JOIN  

(SELECT 
       SUM(PLANNED_QTY) AS 'FUTURE_FCST', 
       MATERIAL, 
       TECHNICAL_INDEX 
FROM   VW_PLANNED_REQMNTS_TXT P 
WHERE   REQUIREMENTS_DATE >= GETDATE() 
AND   PLANNED_QTY > 0 
AND   STOCK_CATEGORY IN ('A60385000','A60385003') 
GROUP BY  MATERIAL, 
       TECHNICAL_INDEX, 
       SIZE_LITERAL) AS P2 
ON    P1.MATERIAL = P2.MATERIAL 
AND   P1.TECHNICAL_INDEX = P2.TECHNICAL_INDEX 

LEFT OUTER JOIN 

(SELECT  ON_HAND_QUANTITY, 
       TECHNICAL_INDEX, 
       MATERIAL, 
       STOCK_CATEGORY, 
       PLANT_CODE 
    FROM   VW_INVENTORY I 
    WHERE   STOCK_CATEGORY IN ('A60385000','A60385003') 
    GROUP BY  TECHNICAL_INDEX, 
       MATERIAL, 
       STOCK_CATEGORY, 
       ON_HAND_QUANTITY, 
       PLANT_CODE) AS I1 
    ON   P1.MATERIAL = I1.MATERIAL 
    AND   P1.TECHNICAL_INDEX = I1.TECHNICAL_INDEX 
    AND   P1.PLANT_CODE = I1.PLANT_CODE 

    LEFT OUTER JOIN 

(SELECT  M.material_number, 
       M.material_desc, 
       M.division_id, 
       D.division_desc, 
       M.gender_id, 
       G.gender_desc 
FROM   MaterialMaster.dbo.Material M 

JOIN   MaterialMaster.dbo.Ref_Division D 
ON    M.division_id = D.division_id 
JOIN   MaterialMaster.dbo.Ref_Gender G 
ON    M.gender_id = G.gender_id) AS M1 

ON    P1.MATERIAL = M1.material_number 


GROUP BY  P1.PLANT_CODE, 
       P1.STOCK_CATEGORY, 
       P1.MATERIAL, 
       P1.DISTRIBUTION_VERSION_CODE, 
       P1.PERIOD_CODE, 
       P1.REQUIREMENTS_DATE, 
       P1.[REM PLAN QTY], 
       P1.VERSION_IND_FLAG, 
       P1.WITHDRAWN_QUANTITY, 
       P1.SIZE_LITERAL, 
       P1.TECHNICAL_INDEX, 
       P1.[ORIGINAL FCST QTY], 
       P2.FUTURE_FCST, 
       M1.material_desc, 
       M1.division_id, 
       M1.division_desc, 
       M1.gender_id, 
       M1.gender_desc) AS T1 /* T1 Represents "Total" for all */ 

GROUP BY  PLANT_CODE, 
       STOCK_CATEGORY, 
       MATERIAL, 
       material_desc, 
       division_id, 
       division_desc, 
       gender_id, 
       gender_desc, 
       DISTRIBUTION_VERSION_CODE, 
       PERIOD_CODE, 
       REQUIREMENTS_DATE, 
       VERSION_IND_FLAG, 
       TECHNICAL_INDEX, 
       SIZE_LITERAL, 
       [ORIGINAL FCST QTY], 
       WITHDRAWN_QUANTITY, 
       [REM PLAN QTY], 
       FUTURE_FCST, 
       TOTAL_OH_INV 
+3

我有一条经验法则。如果我必须使用“选择不同”,我做了一些错误的事情,或者至少我可以做得更好。 [本文](http://weblogs.sqlteam.com/markc/archive/2008/11/11/60752.aspx)解释得很好。 – mason 2014-09-13 03:13:02

+0

简而言之 - 从未 - 需要在已使用“group by”的单个查询中包含“distinct”;它只是多余的。 @mason我也喜欢那篇文章 – 2014-09-13 07:55:47

+0

'select distinct'产生**行**,它们是唯一的,**整行**被考虑。所以,如果你已经使用选择不同的,你仍然认为信息不是“独特的”,那么你只是没有使用正确的技术。但是:没有你通过一些数据展示你的问题真的是我们可能猜测了很长时间;但通常row_number()解决了这种情况。您确实需要提供样本数据和预期结果(或更好地设置sqlfiddle) – 2014-09-13 08:01:51

回答

0

您使用2次GROUP BY子句来做同样的事情。外部GROUP BY不起作用。此外,如果您已经使用GROUP BY,则使用DISTINCT意味着somethig错误,正如@mason在他的评论中指出的那样。你试图删除一些行,但它不是一个好的方法去,它只是混淆了这个问题。

另一个建议:对于字段名称使用[]字符而不是'字符,例如, M1.material_desc AS [MATERIAL_DESC]。它会提高你的SQL的可读性,这是你需要严格写更长的查询 - char文字是红色的。

所以内部查询 - 有问题的部分 - 应该被重新格式化,这样能够阅读:

SELECT P1.PLANT_CODE, P1.STOCK_CATEGORY, P1.MATERIAL, M1.material_desc AS [MATERIAL_DESC], M1.division_id AS [DIVISION_ID], 
     UPPER(M1.division_desc) AS [DIVISION_DESC], UPPER(M1.gender_id) AS [GENDER_ID], UPPER(M1.gender_desc) AS [GENDER_DESC], 
     P1.DISTRIBUTION_VERSION_CODE, P1.PERIOD_CODE, P1.REQUIREMENTS_DATE, P1.VERSION_IND_FLAG, P1.TECHNICAL_INDEX, P1.SIZE_LITERAL, 
     P1.[ORIGINAL FCST QTY], P1.WITHDRAWN_QUANTITY, P1.[REM PLAN QTY], P2.[FUTURE_FCST], SUM(I1.ON_HAND_QUANTITY) 
     AS [TOTAL_OH_INV] 
     FROM (SELECT PLANT_CODE, STOCK_CATEGORY, MATERIAL, DISTRIBUTION_VERSION_CODE, PERIOD_CODE, REQUIREMENTS_DATE, 
        PLANNED_QTY AS [REM PLAN QTY], VERSION_IND_FLAG, SIZE_LITERAL, WITHDRAWN_QUANTITY, TECHNICAL_INDEX, 
        PLANNED_QTY + WITHDRAWN_QUANTITY AS [ORIGINAL FCST QTY] 
       FROM VW_PLANNED_REQMNTS_TXT 
       WHERE (PLANT_CODE IN ('6040', '6041')) AND (STOCK_CATEGORY IN ('A60385000', 'A60385003')) 
         AND (DISTRIBUTION_VERSION_CODE IN ('00', '01', 'ZU', 'Z2')) 
         AND (REQUIREMENTS_DATE < GETDATE() - @daynumber) AND (PLANNED_QTY > 0) 
     ) AS P1 LEFT OUTER JOIN 
        (SELECT SUM(PLANNED_QTY) AS [FUTURE_FCST], MATERIAL, TECHNICAL_INDEX 
        FROM VW_PLANNED_REQMNTS_TXT AS P 
        WHERE (REQUIREMENTS_DATE >= GETDATE()) AND (PLANNED_QTY > 0) 
          AND (STOCK_CATEGORY IN ('A60385000', 'A60385003')) 
        GROUP BY MATERIAL, TECHNICAL_INDEX, SIZE_LITERAL 
     ) AS P2 ON P1.MATERIAL = P2.MATERIAL AND P1.TECHNICAL_INDEX = P2.TECHNICAL_INDEX 
     LEFT OUTER JOIN 
        (SELECT ON_HAND_QUANTITY, TECHNICAL_INDEX, MATERIAL, STOCK_CATEGORY, PLANT_CODE 
        FROM VW_INVENTORY AS I 
        WHERE (STOCK_CATEGORY IN ('A60385000', 'A60385003')) 
        GROUP BY TECHNICAL_INDEX, MATERIAL, STOCK_CATEGORY, ON_HAND_QUANTITY, PLANT_CODE 
     ) AS I1 ON P1.MATERIAL = I1.MATERIAL AND P1.TECHNICAL_INDEX = I1.TECHNICAL_INDEX AND P1.PLANT_CODE = I1.PLANT_CODE 
     LEFT OUTER JOIN 
       (SELECT M.material_number, M.material_desc, M.division_id, D.division_desc, M.gender_id, G.gender_desc 
       FROM  MaterialMaster.dbo.Material AS M 
       INNER JOIN MaterialMaster.dbo.Ref_Division AS D ON M.division_id = D.division_id 
       INNER JOIN MaterialMaster.dbo.Ref_Gender AS G ON M.gender_id = G.gender_id 
     ) AS M1 ON P1.MATERIAL = M1.material_number 
GROUP BY PLANT_CODE, STOCK_CATEGORY, MATERIAL, DISTRIBUTION_VERSION_CODE, PERIOD_CODE, REQUIREMENTS_DATE, 
     P1.[REM PLAN QTY], P1.VERSION_IND_FLAG, P1.WITHDRAWN_QUANTITY, P1.SIZE_LITERAL, P1.TECHNICAL_INDEX, P1.[ORIGINAL FCST QTY], 
     P2.[FUTURE_FCST], M1.material_desc, M1.division_id, M1.division_desc, M1.gender_id, M1.gender_desc 

在这里,你应该找你的问题。

检查每个内部SELECT分别验证它是否返回所需的结果。问题可能是您从VW_PLANNED_REQMNTS_TXT有两次SELECT。我建议你尝试删除P2子查询,看看会发生什么。为什么P2不是P1子查询的一部分?

 FROM (SELECT PLANT_CODE, STOCK_CATEGORY, MATERIAL, DISTRIBUTION_VERSION_CODE, PERIOD_CODE, REQUIREMENTS_DATE, 
        PLANNED_QTY AS [REM PLAN QTY], VERSION_IND_FLAG, SIZE_LITERAL, WITHDRAWN_QUANTITY, TECHNICAL_INDEX, 
        PLANNED_QTY + WITHDRAWN_QUANTITY AS [ORIGINAL FCST QTY] 
        (SELECT SUM(PLANNED_QTY) 
        FROM VW_PLANNED_REQMNTS_TXT 
        WHERE (REQUIREMENTS_DATE >= GETDATE()) AND (PLANNED_QTY > 0) 
          AND (STOCK_CATEGORY IN ('A60385000', 'A60385003')) 
          AND MATERIAL=P.MATERIAL AND TECHNICAL_INDEX=P.TECHNICAL_INDEX 
        GROUP BY SIZE_LITERAL) AS [FUTURE_FCST] 
       FROM VW_PLANNED_REQMNTS_TXT P 
       WHERE (PLANT_CODE IN ('6040', '6041')) AND (STOCK_CATEGORY IN ('A60385000', 'A60385003')) 
         AND (DISTRIBUTION_VERSION_CODE IN ('00', '01', 'ZU', 'Z2')) 
         AND (REQUIREMENTS_DATE < GETDATE() - @daynumber) AND (PLANNED_QTY > 0) 
     ) AS P1 
     LEFT OUTER JOIN 
        (SELECT ON_HAND_QUANTITY, TECHNICAL_INDEX, MATERIAL, STOCK_CATEGORY, PLANT_CODE 

此外,左外连接可以产生没有任何材料的行。为什么不用INNER JOIN?

但是,您的问题不能在最终的GROUP BY子句中奇迹般地解决,因为您只有SUM所有选定字段中的一个字段。

相关问题