在使用sql中的行的值定义新列之后,我想要一个新列,它将是列的总和

时间:2015-02-08 06:59:55

标签: sql sql-server sql-server-2012 case

我有使用行值定义新列的查询。现在我想要另一个列,它将是新列的总和。我试过这个,

SET @SQL = '
SELECT SC.Name AS BUYER, 
CASE WHEN PPC.FactoryName = ''ANANTA'' THEN OM.OrderQty END AS Unit1_Qty,
CASE WHEN PPC.FactoryName = ''ACWL'' THEN OM.OrderQty END AS Unit2_Qty,
CASE WHEN PPC.FactoryName = ''DNV'' THEN OM.OrderQty END AS Unit3_Qty,
CASE WHEN PPC.FactoryName = ''ANANTA'' THEN OM.OrderQty * FR.Rate END AS Unit1_Value, 
CASE WHEN PPC.FactoryName = ''ACWL'' THEN OM.OrderQty * FR.Rate END AS Unit2_Value, 
CASE WHEN PPC.FactoryName = ''DNV'' THEN OM.OrderQty * FR.Rate END AS Unit3_Value,

(Unit1_Qty + Unit2_Qty + Unit3_Qty) as TotalQty

FROM LineAllocation LA
INNER JOIN OrderMaster OM ON LA.OrderRef= OM.OrderRefID
INNER JOIN AmanOTS..FileRef FR ON FR.FileRefID = OM.FileRefID
INNER JOIN SystemManager..Contacts SC ON SC.Code=OM.BuyerCode
INNER JOIN SystemManager..ProductionProcessCostCenter PPC ON PPC.CostCenter= LA.Line
INNER JOIN OrderMasterCostBreakdown OCB ON OCB.OrderRefID= OM.OrderRefID
INNER JOIN SystemManager..ProductionProcess PP ON PP.ProcessID = PPC.ProcessId
where UseDate = '''+Cast(@MonthName As Varchar)+''' AND  ProcessName =''Sewing'' 
'
Exec(@sql)

但它不起作用并显示使用别名的错误。

  

Msg 207,Level 16,State 1,Line 10
  列名称无效' Unit1_Qty'。

     

Msg 207,Level 16,State 1,Line 10
  列名称无效' Unit2_Qty'。

     

Msg 207,Level 16,State 1,Line 10
  列名称无效' Unit3_Qty'。

我该怎么做?

2 个答案:

答案 0 :(得分:3)

在表达式中使用列别名的一种方法是使用公用表表达式。下面的示例也是参数化查询,而不是字符串连接。

SET @SQL = '
WITH
    allocations AS (
        SELECT SC.Name AS BUYER, 
            CASE WHEN PPC.FactoryName = ''ANANTA'' THEN OM.OrderQty END AS Unit1_Qty,
            CASE WHEN PPC.FactoryName = ''ACWL'' THEN OM.OrderQty END AS Unit2_Qty,
            CASE WHEN PPC.FactoryName = ''DNV'' THEN OM.OrderQty END AS Unit3_Qty,
            CASE WHEN PPC.FactoryName = ''ANANTA'' THEN OM.OrderQty * FR.Rate END AS Unit1_Value, 
            CASE WHEN PPC.FactoryName = ''ACWL'' THEN OM.OrderQty * FR.Rate END AS Unit2_Value, 
            CASE WHEN PPC.FactoryName = ''DNV'' THEN OM.OrderQty * FR.Rate END AS Unit3_Value
        FROM LineAllocation LA
        INNER JOIN OrderMaster OM ON LA.OrderRef= OM.OrderRefID
        INNER JOIN AmanOTS..FileRef FR ON FR.FileRefID = OM.FileRefID
        INNER JOIN SystemManager..Contacts SC ON SC.Code=OM.BuyerCode
        INNER JOIN SystemManager..ProductionProcessCostCenter PPC ON PPC.CostCenter= LA.Line
        INNER JOIN OrderMasterCostBreakdown OCB ON OCB.OrderRefID= OM.OrderRefID
        INNER JOIN SystemManager..ProductionProcess PP ON PP.ProcessID = PPC.ProcessId
        where UseDate = @MonthName AND ProcessName =''Sewing'' 
        )
SELECT 
    BUYER, 
    Unit1_Qty,
    Unit2_Qty,
    Unit3_Qty,
    Unit1_Value, 
    Unit2_Value, 
    Unit3_Value,
    (Unit1_Qty + Unit2_Qty + Unit3_Qty) as TotalQty
FROM allocations;'

EXEC sp_executesql
    @sql
    ,N'@MonthName varchar(30)'
    ,@MonthName = @MonthName;

答案 1 :(得分:1)

没有什么复杂的。对于任何给定的行,根据工厂名称,您只有一个数量和一个值。

Factory  Qty1 Qty2 Qty3 Val1 Val2 Val3
=======  ==== ==== ==== ==== ==== ====
ANANTA   10   NULL NULL 12.5 NULL NULL
ACWL     NULL 20   NULL NULL 22.5 NULL
DNV      NULL NULL 30   NULL NULL 32.5

因此,只需在最后不加选择地计算价值即可得到你想要的东西:

...
CASE WHEN PPC.FactoryName = ''DNV'' THEN OM.OrderQty * FR.Rate END AS Unit3_Value,
OM.OrderQty * FR.Rate as TotalVal
...

你最终会得到这样的东西:

Factory  Qty1 Qty2 Qty3 Val1 Val2 Val3 TotalVal
=======  ==== ==== ==== ==== ==== ==== ========
ANANTA     10 NULL NULL 12.5 NULL NULL     12.5
ACWL     NULL   20 NULL NULL 22.5 NULL     22.5
DNV      NULL NULL   30 NULL NULL 32.5     32.5

附录:正如分手一样,如果三个Valx字段中的任何一个或全部都有值,那么求和字段将如下所示。

...
S1.OrderQty * FR.Rate END AS Unit1_Value,
S2.OrderQty * FR.Rate END AS Unit2_Value,
S3.OrderQty * FR.Rate END AS Unit3_Value,
( Nvl( S1.OrderQty, 0 )
+ Nvl( S2.OrderQty, 0 )
+ Nvl( S3.OrderQty, 0 )) * FR.Rate END AS TotalVal

然后结果如下:

...  Qty1 Qty2 Qty3 Val1 Val2 Val3 TotalVal
===  ==== ==== ==== ==== ==== ==== ========
...    10   20   30 12.5 25.0 37.5    75.00
...    10 null   30 12.5 null 37.5    50.00