SQL CASE WHEN缩小结果,改变字段

时间:2013-11-07 07:20:14

标签: sql case-when

我已经阅读了几十个关于CASE的答案,我不确定这是我需要在这里使用的内容,它似乎应该有用但不是:

Data:
OrderNum    OrderLine  PartNum
200011         1         ABC-1
200011         2         DEF-1
200012         1         XYZ-1

What I would like to return:
OrderNum   Item#
200011     MIXED
200012     XYZ-1


What I am returning instead:
OrderNum   Item#
200011     ABC-1
200011     MIXED
200012     XYZ-1

我的查询:

SELECT OrderHed.OrderNum, 
      (CASE WHEN ShipDtl.OrderLine > '1' then 'MIXED' else ShipDtl.PartNum end) as [Item#]
FROM dbo.OrderHed, dbo.ShipDtl
WHERE ShipDtl.Company = OrderHed.Company 
AND ShipDtl.OrderNum = OrderHed.OrderNum
GROUP BY OrderHed.OrderNum, ShipDtl.OrderLine, ShipDtl.Part

3 个答案:

答案 0 :(得分:1)

尝试分组

SELECT OrderHed.OrderNum, 
      (CASE WHEN SUM(ShipDtl.OrderLine) > 1 then 'MIXED' else MAX(ShipDtl.PartNum) end) as [Item#]
FROM dbo.OrderHed, dbo.ShipDtl
WHERE ShipDtl.Company = OrderHed.Company 
AND ShipDtl.OrderNum = OrderHed.OrderNum
GROUP BY OrderHed.OrderNum

SQLFiddle演示:http://sqlfiddle.com/#!3/209d8/1

答案 1 :(得分:1)

您没有编写您使用的数据库引擎,但如果它是SQL 2005及更高版本,我认为使用COUNT的窗口函数会使事情变得更容易,因为您不需要分组。

SELECT  DISTINCT
        OrderHed.OrderNum ,
        CASE 
            WHEN COUNT(ShipDtl.OrderLine) OVER (PARTITION BY ShipDtl.OrderNum) > 1 THEN 'MIXED'
            ELSE PartNum
        END AS [Item#]
FROM    dbo.OrderHed ,
        dbo.ShipDtl
WHERE   ShipDtl.Company = OrderHed.Company
        AND ShipDtl.OrderNum = OrderHed.OrderNum

你需要DISTINCT,因为它会为每行选择一行,但每行多行都会混合,所以你可以轻松区分。

这将简单地选择OrderNum,如果每个ordernum Count(xxx)OVER(按yyy分区)存在多个订单行,则它将选择'MIXED',否则选择partnum。 然后区分结果。

答案 2 :(得分:0)

没有强制使用CASE(是吗?)。

在您的示例中,CASE用于执行逻辑OR。还有其他方法可以在SQL中执行逻辑OR,例如UNION

WITH T 
     AS
     (
      SELECT OrderHed.OrderNum, ShipDtl.PartNum, ShipDtl.OrderLine
        FROM dbo.OrderHed, dbo.ShipDtl
       WHERE ShipDtl.Company = OrderHed.Company 
             AND ShipDtl.OrderNum = OrderHed.OrderNum
     )
SELECT OrderNum, PartNum
  FROM T
 WHERE OrderLine = 1
       AND OrderNum NOT IN ( 
                            SELECT OrderNum
                              FROM T T2
                             WHERE OrderLine > 1
                           )
UNION
SELECT OrderNum, 'MIXED' AS PartNum
  FROM T
 WHERE OrderLine > 1;