复杂的 Sql 案例语句得到错误的结果集

Complicated Sql Case Statement Getting the Wrong Result Set

原始访问查询

IIf([Package Type]="Bar",10,IIf([upper limit unit]="g",([UL3]*[weight factor]),[piece wt (g)]*[Upper Limit Factor])) AS [Upper Limit (g)]

SQL转换

SELECT CASE WHEN [Package Type] = 'Bar' Then 10 
CASE WHEN [Upper Limit Unit] = 'g' Then ([UL3)] * [Weight Factor]
ELSE [Peice Wt(g)] * [Upper Limit Factor] END AS [Upper Limit (g)]

我得到了一个 "Syntax error near the keyword ELSE",查询的各个部分工作得很好。

如何在 case 语句中引用多个 case 语句?请帮忙

SELECT 
    CASE WHEN [Package Type] = 'Bar' THEN 10
    CASE WHEN [Upper Limit Unit] = 'g' 
           THEN CASE WHEN [Package Type] != NULL
                     THEN ([mav (g)] - [scale deviation factor] - [tare variation factor (g)]) / NULLIF ([weight factor], 0) 
           WHEN (mav.[MAV (g)] - pl.[Scale Deviation Factor] - nwmd.[Tare Variation Factor (g)]) 
                 / NULLIF (nwmd.[Weight Factor], 0) 
                 - CAST((mav.[MAV (g)] - pl.[Scale Deviation Factor] - nwmd.[Tare Variation Factor (g)]) 
                 / NULLIF (nwmd.[Weight Factor], 0) AS Int) 
                 = 0 
           THEN CAST((mav.[MAV (g)] - pl.[Scale Deviation Factor] - nwmd.[Tare Variation Factor (g)])
                / NULLIF (nwmd.[Weight Factor], 0) AS Int) 
           WHEN (mav.[MAV (g)] - pl.[Scale Deviation Factor] - nwmd.[Tare Variation Factor (g)]) 
                 / NULLIF (nwmd.[Weight Factor], 0) 
                 - CAST((mav.[MAV (g)] - pl.[Scale Deviation Factor] - nwmd.[Tare Variation Factor (g)]) 
                 / NULLIF (nwmd.[Weight Factor], 0) AS Int) > 0 
                 AND 
                 (mav.[MAV (g)] - pl.[Scale Deviation Factor] - nwmd.[Tare Variation Factor (g)]) 
                 / NULLIF (nwmd.[Weight Factor], 0) 
                 - CAST((mav.[MAV (g)] - pl.[Scale Deviation Factor] - nwmd.[Tare Variation Factor (g)]) 
                 / NULLIF (nwmd.[Weight Factor], 0) AS Int)  < 0.51 
           THEN CAST((mav.[MAV (g)] - pl.[Scale Deviation Factor] - nwmd.[Tare Variation Factor (g)])
                / NULLIF (nwmd.[Weight Factor], 0) AS Int) 
                + [Rounding Factor1] ELSE CAST((mav.[MAV (g)] - pl.[Scale Deviation Factor] - nwmd.[Tare Variation Factor (g)])
                / NULLIF (nwmd.[Weight Factor], 0) AS Int) + [Rounding Factor2] * NULLIF ( [Weight Factor],0)
           ELSE CASE WHEN [Upper Limit Unit] != 'g' 
                     THEN ([Label Wt (g)] / [Pcs Per Unit]) * [Upper Limit Factor] END AS [Upper Limit (g)]

FROM
    dbo.[Net Weight Master Data] nwmd
LEFT OUTER JOIN 
    dbo.[Production Lines] pl ON nwmd.[Production Line] = pl.[Production Line] 
INNER JOIN 
    dbo.[Maximum Allowable Variations] mav ON nwmd.[Label Wt (g)] = mav.[Labeled Quantity (g)] 
LEFT OUTER JOIN 
    dbo.ItemDescription I ON nwmd.[Unit UPC Base Item] = I.[Unit UPC Base Item]
ORDER BY 
    nwmd.[Unit UPC Base Item], 
    nwmd.[Production Line]  

您有 4 CASE 而只有 1 个 END,所以这行不通。

这是一团糟,但理想情况下,您可以打破通用标准来清理它,使用多个步骤比一个嵌套的 CASE 查询更容易阅读。

至少你需要更多 END,缩进有助于隔离错误:

SELECT 
CASE WHEN [Package Type] = 'Bar' 
     THEN 10 
     ELSE CASE WHEN [Upper Limit Unit] = 'g' 
               THEN CASE WHEN [Package Type] IS NOT NULL 
                         THEN ([mav (g)] - [scale deviation factor] - [tare variation factor (g)]) / NULLIF ([weight factor], 0) 
                         WHEN (MAV.[MAV (g)] - PL.[Scale Deviation Factor] - NWMD.[Tare Variation Factor (g)]) 
                                / NULLIF (NWMD.[Weight Factor], 0) - CAST((MAV.[MAV (g)] - PL.[Scale Deviation Factor] 
                                - NWMD.[Tare Variation Factor (g)]) / NULLIF (NWMD.[Weight Factor], 0) AS Int) = 0 
                         THEN CAST((MAV.[MAV (g)] - PL.[Scale Deviation Factor] - NWMD.[Tare Variation Factor (g)])
                            / NULLIF (NWMD.[Weight Factor], 0) AS Int) 
                         WHEN (MAV.[MAV (g)] - PL.[Scale Deviation Factor] - NWMD.[Tare Variation Factor (g)]) 
                            / NULLIF (NWMD.[Weight Factor], 0) - CAST((MAV.[MAV (g)] - PL.[Scale Deviation Factor] 
                            - NWMD.[Tare Variation Factor (g)]) / NULLIF (NWMD.[Weight Factor], 0) AS Int) > 0 AND 
                            (MAV.[MAV (g)] - PL.[Scale Deviation Factor] - NWMD.[Tare Variation Factor (g)]) 
                            / NULLIF (NWMD.[Weight Factor], 0) - CAST((MAV.[MAV (g)] - PL.[Scale Deviation Factor] 
                            - NWMD.[Tare Variation Factor (g)]) / NULLIF (NWMD.[Weight Factor], 0) AS Int) 
                            < 0.51 
                        THEN CAST((MAV.[MAV (g)] - PL.[Scale Deviation Factor] - NWMD.[Tare Variation Factor (g)])
                            / NULLIF (NWMD.[Weight Factor], 0) AS Int) + [Rounding Factor1] 
                        ELSE CAST((MAV.[MAV (g)]  
                          - PL.[Scale Deviation Factor] - NWMD.[Tare Variation Factor (g)])
                           / NULLIF (NWMD.[Weight Factor], 0) AS Int) + [Rounding Factor2] * NULLIF ( [Weight Factor],0) 
                        ELSE CASE WHEN [Upper Limit Unit] != 'g' --Double ELSE!
                                  THEN ([Label Wt (g)] / [Pcs Per Unit]) * [Upper Limit Factor] 
                             END
                  END
        END
END AS [Upper Limit (g)]
FROM         dbo.[Net Weight Master Data] NWMD LEFT OUTER JOIN
                      dbo.[Production Lines] PL ON NWMD.[Production Line] = PL.[Production Line] INNER JOIN
                      dbo.[Maximum Allowable Variations] MAV ON NWMD.[Label Wt (g)] = MAV.[Labeled Quantity (g)] LEFT OUTER JOIN
                      dbo.ItemDescription ID ON NWMD.[Unit UPC Base Item] = ID.[Unit UPC Base Item]
ORDER BY NWMD.[Unit UPC Base Item], NWMD.[Production Line]  

更新:还发现一个 CASE 中有 2 个 ELSE,上面用 --Double ELSE! 指出,每个 CASE 只能有一个 ELSE。正如 Aaron 指出的那样,您那里还有一个 != NULL,您在那里需要 IS NOT NULL。另外添加了 table 别名以进一步清理。

虽然我预先格式化了你的原件以查看 case/when/then 构造的对齐失败,但我更进一步简化了可读性,通过创建新的简化列来对数据元素进行预查询您的 "mav - scale - tare" 和 NULLIF( weight factor ),并再次作为单个 "DivideTest" 通过 "mav - scale - tare" / NULLIF( weight factor, 0 ) 来自您的原始数据。

这允许外部查询使用这些简化的列名称作为案例构造的基础以提高可读性。

我仍然不知道你在各自的休息时间想达到什么目的,但希望这个版本能让你更清楚地知道你想达到什么目的。而且我知道我没有适当的 ELSE/END 组件,因为不清楚你想要达到什么目的。最后,我希望您知道除以零是一个无效值,因此当您测试 NULLIF( [weight factor], 0 ) 时可能会导致您的案例结构出现问题。

SELECT
      CASE WHEN PQ.pkgType = 'Bar' 
           THEN 10
           ELSE CASE WHEN [Upper Limit Unit] = 'g' 
                     THEN CASE WHEN PQ.pkgType != NULL
                                   THEN PQ.DivideTest
                               WHEN PQ.DivideTest - CAST( PQ.DivideTest AS Int) = 0 
                                   THEN CAST( PQ.DivideTest AS Int) = 0 
                               WHEN PQ.DivideTest - CAST( PQ.DivideTest AS Int) > 0 
                                           AND 
                                    PQ.DivideTest - CAST( PQ.DivideTest AS Int) < 0.51
                                  THEN CAST( PQ.DivideTest AS Int) + PQ.roundFactor1

                                  ELSE CAST( PQ.DivideTest AS Int) + PQ.roundFactor2 * PQ.WeightFactor
                                  END
                     ELSE CASE WHEN [Upper Limit Unit] != 'g' 
                     THEN PQ.notGWeight END AS [Upper Limit (g)]
           END
   from 
      ( SELECT 
              [Package Type] pkgType,
              [Upper Limit Unit] upperLimitUnit,
              NULLIF (nwmd.[weight factor], 0)  as weightFactor,
              (mav.[mav (g)] - pl.[scale deviation factor] - nwmd.[tare variation factor (g)]) / NULLIF (nwmd.[weight factor], 0) as DivideTest,
              [Rounding Factor1] roundFactor1,
              [Rounding Factor2] roundFactor2,
              ([Label Wt (g)] / [Pcs Per Unit]) * [Upper Limit Factor] notGWeight
           FROM
              dbo.[Net Weight Master Data] nwmd
                 LEFT OUTER JOIN dbo.[Production Lines] pl
                    ON nwmd.[Production Line] = pl.[Production Line] 
                 INNER JOIN dbo.[Maximum Allowable Variations] mav
                    ON nwmd.[Label Wt (g)] = mav.[Labeled Quantity (g)] 
                 LEFT OUTER JOIN dbo.ItemDescription I 
                    ON nwmd.[Unit UPC Base Item] = I.[Unit UPC Base Item]
           ORDER BY 
              nwmd.[Unit UPC Base Item], 
              nwmd.[Production Line] ) PQ

在使用了所有感谢的帮助后,我仍然面临语法问题,我通过将 "End" 放在相应的位置并删除查询中的额外 "Else" 和最终有效的查询来解决这些问题是:

SELECT [wmd].[Unit UPC Base Item], 
    CASE WHEN [Package Type] = 'Bar' Then 10  
            WHEN [Upper Limit Unit] != 'g' THEN ([Label Wt (g)] / [Pcs Per Unit])* ([Upper Limit Factor]) 
                WHEN [Upper Limit Unit] = 'g' THEN 
    CASE WHEN [Package Type] IS NOT NULL THEN ([mav (g)] - [scale deviation factor] - [tare variation factor (g)]) / NULLIF ([weight factor], 0) 
             WHEN (mav.[MAV (g)] - prod.[Scale Deviation Factor] - wmd.[Tare Variation Factor (g)]) 
                      / NULLIF (wmd.[Weight Factor], 0) 
                      - CAST((mav.[MAV (g)] - prod.[Scale Deviation Factor] - [wmd].[Tare Variation Factor (g)]) 
                      / NULLIF (wmd.[Weight Factor], 0) AS Int) 
                      = 0 THEN CAST((mav.[MAV (g)] - prod.[Scale Deviation Factor] - [wmd].[Tare Variation Factor (g)])
                       / NULLIF (wmd.[Weight Factor], 0) AS Int) 
             WHEN (mav.[MAV (g)] - prod.[Scale Deviation Factor] - [wmd].[Tare Variation Factor (g)]) 
                      / NULLIF (wmd.[Weight Factor], 0) 
                      - CAST((mav.[MAV (g)] - prod.[Scale Deviation Factor] - [wmd].[Tare Variation Factor (g)]) 
                      / NULLIF (wmd.[Weight Factor], 0) AS Int) > 0 AND 
                      (mav.[MAV (g)] - prod.[Scale Deviation Factor] - [wmd].[Tare Variation Factor (g)]) 
                      / NULLIF (wmd.[Weight Factor], 0) 
                      - CAST((mav.[MAV (g)] - prod.[Scale Deviation Factor] - [wmd].[Tare Variation Factor (g)]) 
                      / NULLIF (wmd.[Weight Factor], 0) AS Int) 
                      < 0.51 THEN CAST((mav.[MAV (g)] - prod.[Scale Deviation Factor] - [wmd].[Tare Variation Factor (g)])
                       / NULLIF (wmd.[Weight Factor], 0) AS Int) 
                      + [Rounding Factor1] 
             ELSE CAST((mav.[MAV (g)] - prod.[Scale Deviation Factor] - [wmd].[Tare Variation Factor (g)])
                       / NULLIF (wmd.[Weight Factor], 0) AS Int) + [Rounding Factor2]  
              END *([Weight Factor])
              END AS [UpperLimit(g)] 

FROM         dbo.[Net Weight Master Data] AS wmd LEFT OUTER JOIN
                      dbo.[Production Lines] AS prod ON wmd.[Production Line] = prod.[Production Line] INNER JOIN
                      dbo.[Maximum Allowable Variations] AS mav ON wmd.[Label Wt (g)] = mav.[Labeled Quantity (g)] LEFT OUTER JOIN
                      dbo.ItemDescription ON wmd.[Unit UPC Base Item] = dbo.ItemDescription.[Unit UPC Base Item]
ORDER BY wmd.[Unit UPC Base Item], wmd.[Production Line]