基于SELECT字段中的一个值选择大型查询中的最新记录

时间:2014-09-13 03:08:00

标签: sql sql-server database sql-server-2008 join

我有一个大的查询,相对较大。即使我已指定' DISTINCT',此查询也会在MATERIAL列上不断生成多个结果。我想通过指定' DISTINCT'并总结我需要的值,它将产生每个MATERIAL数一行。任何人都可以帮我看看我在这里做错了什么。我意识到最后一个子查询在这一点上可能是多余的 - 我正在测试,这就是我得到的结果。

提前谢谢。

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

1 个答案:

答案 0 :(得分:0)

您使用2次GROUP BY子句执行相同的操作。外GROUP BY没有效果。此外,当你已经使用DISTINCT时,使用GROUP BY意味着,某些事情是错误的,正如@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

LEFT OUTER JOIN也可以生成没有任何MATERIAL的行。为什么不加入INNER?

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