2016-06-21 187 views
3

我已经在#temp表如下数据:聚合函数

Id code  Fname  CompanyId FieldName   Value 
---------------------------------------------------------------- 
465 00133 JENN WILSON  1   ERA    1573 
465 00133 JENN WILSON  1   ESHIFTALLOW  3658 
465 00133 JENN WILSON  1   NETPAY   51560 

我想要做以下操作即

一行将另外两列,即ERA + ESHIFTALLOW 其他行将被扣除&三列的补充,即NETPAY - ERA + ESHIFTALLOW 我曾尝试在SQL Server中使用case语句。

要求如下

的输出,其中Field1= ERA + ESHIFTALLOW & Filed2=NETPAY - ERA + ESHIFTALLOW

Id code  Fname  CompanyId FieldName   Value 
---------------------------------------------------------------- 
465 00133 JENN WILSON  1   Field1   5231 
465 00133 JENN WILSON  1   Filed2   46329 

我曾使用SQL Server Case语句,但没有得到适当的输出 SQL查询尝试:Aggregate option in SQL Server CASE statement

回答

3

我看到至少有两种方法来获得这些结果。一个组或一个关键点

在下面的示例中显示了2个方法。

CREATE TABLE #Temp (Id INT, code VARCHAR(5), Fname VARCHAR(20), CompanyId INT, FieldName VARCHAR(20), Value INT); 

insert into #Temp (Id, code, Fname, CompanyId, FieldName, Value) 
values 
(465,00133,'JENN WILSON',1,'ERA',1573), 
(465,00133,'JENN WILSON',1,'ESHIFTALLOW',3658), 
(465,00133,'JENN WILSON',1,'NETPAY',51560); 

with Q AS (
    SELECT Id, code, Fname, CompanyId, 
    sum(case when FieldName = 'ERA' then Value end) as ERA, 
    sum(case when FieldName = 'ESHIFTALLOW' then Value end) as ESHIFTALLOW, 
    sum(case when FieldName = 'NETPAY' then Value end) as NETPAY 
    from #Temp 
    group by Id, code, Fname, CompanyId 
) 
select Id, code, Fname, CompanyId, 'Field1' as FieldName, (ERA + ESHIFTALLOW) as Value from Q 
union all 
select Id, code, Fname, CompanyId, 'Field2', (NETPAY - ERA + ESHIFTALLOW) from Q 
; 

with Q AS (
    SELECT Id, code, Fname, CompanyId, 
    (ERA + ESHIFTALLOW) as Field1, 
    (NETPAY - ERA + ESHIFTALLOW) as Field2 
    FROM (SELECT * FROM #Temp) s 
    PIVOT (SUM(VALUE) FOR FieldName IN (ERA, ESHIFTALLOW, NETPAY)) p 
) 
select Id, code, Fname, CompanyId, 'Field1' as FieldName, Field1 as Value from Q 
union all 
select Id, code, Fname, CompanyId, 'Field2', Field2 from Q 
; 

注意,SUM(VALUE)代替MAX(VALUE)。在这种情况下,它会产生相同的结果。这真的只是一个选择。

1

我不知道这个解决方案是否接近最高效率,但它应该工作:

SELECT 
    BASE.*, 
    ERA.Value AS ERA, 
    ESALLOW.Value AS ESHIFTALLOW, 
    ERA.Value + ESALLOW.Value AS Field1, 
    etc... 
FROM (
    SELECT DISTINCT Id, code, Fname, CompanyId 
    FROM #TEMP) BASE 
LEFT OUTER JOIN (
    SELECT Id, Value 
    FROM #TEMP 
    WHERE FieldName = 'ERA') ERA 
ON BASE.Id = ERA.Id 
LEFT OUTER JOIN (
    SELECT Id, Value 
    FROM #TEMP 
    WHERE FieldName = 'ESHIFTALLOW') ESALLOW 
ON BASE.Id = ESALLOW.Id 

这为您提供了一个简单的表格,它在单独的列中而不是在单独的行中具有各种类型的值。这使得计算成为可能。

2

大厦倚重LukStorms的回答,您可以使用PIVOT和UNPIVOT得到你想要的结果:

CREATE TABLE #Temp 
    (Id INT, Code VARCHAR(5), Fname VARCHAR(20), CompanyId INT, FieldName VARCHAR(20), Value INT); 

INSERT INTO #Temp 
    (Id, Code, Fname, CompanyId, FieldName, Value) 
VALUES 
    (465,00133, 'JENN WILSON', 1, 'ERA', 1573), 
    (465,00133, 'JENN WILSON', 1, 'ESHIFTALLOW', 3658), 
    (465,00133, 'JENN WILSON', 1, 'NETPAY', 51560); 


SELECT Id, Code, Fname, CompanyId, FieldName, Value 
FROM (
    SELECT Id, Code, Fname, CompanyId, 
    ERA + ESHIFTALLOW AS Field1, 
    NETPAY - ERA + ESHIFTALLOW AS Field2 
    FROM (
     SELECT * 
     FROM #Temp 
    ) AS s 
    PIVOT ( 
     SUM(Value) 
     FOR FieldName IN (ERA, ESHIFTALLOW, NETPAY) 
    ) AS p 
) AS r 
UNPIVOT (
    Value 
    FOR FieldName IN (Field1, Field2) 
) AS u 
; 
+0

没想到这一个的。不错的一个:)对于UNPIVOT来说,最终看起来比联盟更好。 – LukStorms