同一查询中的多个Case生成多行

时间:2013-05-20 20:26:49

标签: sql-server-2008 database-administration sapb1

我的问题实际上是我有多个表,我使用两个case语句为ARV1生成一列,为ICA1生成一列,但我需要在同一排。当我使用case时,生成两列,但值显示为两行。我错过了什么?

问题是,我有一张表OINV的发票,并且有一张表INV5,它是持有税的表,我需要在同一行开具发票,其中所有的税款都在申请的不同栏目中谢谢

这是示例表

CREATE TABLE Invoice
(
  Id INT, InvoiceNumber VARCHAR(10), Total INT    
)

INSERT INTO Invoice
VALUES
(1,'200000',100),
(2,'200001',200),
(3,'200002',500),
(4,'200003',700),
(5,'200004',200),
(6,'200005',100),
(7,'200006',300)

CREATE TABLE HoldingTaxes
(
 Id INT, HoldingTaxCode VARCHAR(10),HoldedAmount INT) 
)

INSERT INTO HoldingTaxes
VALUES
(1,'ARV1',20),
(1,'ARV2',30),
(1,'ARV3',35),
(2,'ICA1',20),
(2,'ARV1',10),
(1,'ICA3',50)

我想要一个返回如下内容的查询:

InvoiceNumber Total  ARV1 ARV2 ARV3  ICA1  ICA2   ICA3
200000          100   20   30   35   null   null   50

这就是我想用真实表格做的事情

SELECT T0.DocNum [No. Factura],
CASE
WHEN t5.WTCode ='ARV1' and (t5.U_Ret_ML <>0 AND t5.U_Ret_ML is not null)
THEN 'Perro1'
else NULL
end AS ARV1
,
CASE
WHEN t5.WTCode ='ICA1' and (t5.U_Ret_ML <>0 AND t5.U_Ret_ML is not null)
THEN 'Perro2'
else NULL
end AS ICA1
FROM OINV T0
INNER JOIN INV1 T1 ON T0.DocEntry = T1.DocEntry
INNER JOIN OSLP T4 ON T0.SlpCode = T4.SlpCode 
INNER JOIN OITM T2 ON T1.ItemCode = T2.ItemCode 
INNER JOIN OITW T3 ON T2.ItemCode = T3.ItemCode
INNER JOIN INV5 T5 ON T5.AbsEntry = T0.DocEntry
WHERE T1.WhsCode = T3.WhsCode`enter code here`
GROUP BY T0.DocNum,T0.DocDate,T0.DocTotal, T0.GrosProfit, T4.SlpName,T5.WTCODE,t5.U_Ret_ML

5 个答案:

答案 0 :(得分:1)

替代方式:

  

SELECT inv.InvoiceNumber,inv.Total,[ARV1],[ARV2],[ARV3],[ICA1],[ICA2],[ICA3]
  来自INVOICE inv
  JOIN(
  SELECT id,[ARV1],[ARV2],[ARV3],[ICA1],[ICA2],[ICA3]
  来自   (SELECT * FROM HoldingTaxes)t1
  PIVOT(SUM(HoldedAmount)for HoldingTaxCode)   ([ARV1],[ARV2],[ARV3],[ICA1],[ICA2],[ICA3]))t2   )ht
  ON inv.id = ht.id

sql fiddle:http://sqlfiddle.com/#!3/ea3a4/10

答案 1 :(得分:0)

两个CASE表达式使用相同的逻辑。只有t5.WTCode中的值不同。由于该列不太可能同时具有值​​ARV1ICA1,因此您将始终在任何行中的至少一个计算列中获得NULL

答案 2 :(得分:0)

您为2个不同的值添加了不同的case语句。因此,对于每一行,其中一行是有效的,而另一行是null,这就是你得到的。

答案 3 :(得分:0)

我会使用PIVOT来解决这个问题 - 正如SQL Fiddle所示:

SELECT  EmpName
       ,CASE WHEN ARV1 > 0 THEN 'PERRO1' ELSE NULL END
       ,CASE WHEN ARV2 > 0 THEN 'PERRO2' ELSE NULL END
       ,CASE WHEN ICA1 > 0 THEN 'PERRO3' ELSE NULL END
FROM (SELECT t0.EmpName, t1.Name, t1.Value 
      FROM Table0 t0 INNER JOIN Table1 t1 ON t0.Id = t1.Id ) as  src 
PIVOT (
  MAX(src.Value) 
  FOR src.Name IN ([ARV1],[ARV2],[ICA1])) as p

http://sqlfiddle.com/#!3/a6ff0/2

如果您遇到问题并愿意分享您的结构,我可以将其与您在SQL Fiddle上使用的内容更加匹配。

编辑:

根据您提供的更新,这是我使用数据透视表创建的小提琴。 http://sqlfiddle.com/#!3/47511/4

SELECT * FROM
(SELECT    InvoiceNumber  = Invoice.InvoiceNumber
         ,Total          = Invoice.Total
         ,HoldingTaxCode = HoldingTaxes.HoldingTaxCode
         ,HoldedAmount   = HoldingTaxes.HoldedAmount
FROM      Invoice  
LEFT JOIN HoldingTaxes 
ON        Invoice.Id = HoldingTaxes.Id) PivotSource
PIVOT
(
 SUM(HoldedAmount) FOR HoldingTaxCode IN(ARV1, ARV2, ARV3, ICA1, ICA2, ICA3)  
) PivotData
ORDER BY InvoiceNumber

答案 4 :(得分:0)

这是我解决问题的方法,感谢大家的帮助

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(t5.WTCode) 
            FROM INV5 T5
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query = 'SELECT Factura, Fecha, SN, TotalFacturaSinImpuesto, Total$Descuento, Total$Impuesto, Total$Retenciones, Total$Factura, CostoTotal$Factura, Margen$Factura, Costo$PromedioInventario, Margen$Inventario, NombreVendedor, ' + @cols + ' from
            (
                select T0.DocNum [Factura], T0.DocDate [Fecha], T0.CardName [SN],SUM(T1.LineTotal) [TotalFacturaSinImpuesto], T0.DiscSum [Total$Descuento],  T0.VatSum [Total$Impuesto],(T0.WTSum*-1) [Total$Retenciones],t5.WTCode [CodigoRetencion],t5.U_Ret_ML [CantidadRetenida],T0.DocTotal [Total$Factura],SUM(T1.GrossBuyPr*T1.Quantity) [CostoTotal$Factura], T0.GrosProfit [Margen$Factura],SUM(T1.Quantity*T3.AvgPrice) [Costo$PromedioInventario],(SUM(T1.LineTotal*T1.Quantity))-(SUM(T1.Quantity*T3.AvgPrice)) [Margen$Inventario], T4.SlpName [NombreVendedor]
                FROM OINV T0
                INNER JOIN INV1 T1 ON T0.DocEntry = T1.DocEntry
                INNER JOIN OSLP T4 ON T0.SlpCode = T4.SlpCode 
                INNER JOIN OITM T2 ON T1.ItemCode = T2.ItemCode 
                INNER JOIN OITW T3 ON T2.ItemCode = T3.ItemCode
                INNER JOIN INV5 T5 ON T5.AbsEntry = T0.DocEntry
                WHERE T1.WhsCode = T3.WhsCode 
                GROUP BY T0.DocNum,T0.DocDate, T0.CardName,T0.BaseAmnt, T0.DiscSum,  T0.VatSum,  T0.WTSum,T0.DocTotal, T0.GrosProfit, T4.SlpName,T5.WTCODE,T5.U_RET_ML
           ) x
            pivot 
            (
                sum(CantidadRetenida)
                for CodigoRetencion in (' + @cols + ')
            ) p '


execute(@query)