如何使用1表中的pivot水平查看sql查询

时间:2016-06-20 07:03:06

标签: sql sql-server

表。table

我的桌子行。一月份

january result

2月份的行

february result

我的示例查询

select id2,
(select budget from tblmonth where id2='1' and month='January' and groups='CCARE') as jbud1,
(select actual from tblmonth where id2='1' and month='January' and groups='CCARE') as jact1,
(select variance from tblmonth where id2='1' and month='January' and groups='CCARE') as jvar1,
(select [percent] from tblmonth where id2='1' and month='January' and groups='CCARE') as jper1,

(select budget from tblmonth where id2='2' and month='February' and groups='CCARE') as fbud2,
(select actual from tblmonth where id2='2' and month='February' and groups='CCARE') as fact2,
(select variance from tblmonth where id2='2' and month='February' and groups='CCARE') as fvar2,
(select [percent] from tblmonth where id2='2' and month='February' and groups='CCARE') as fper2


 from tblmonth where groups='CCARE' and id2='1' and month='January'

我对此查询的问题是它返回重复值。 duplicate

我想实现的是。

每个月的列预算,实际值,差异,百分比将在单个结果中显示。像这样在图像中。

want to achieved

提前感谢:)我只是sql和我使用sql server 2014的新手。

3 个答案:

答案 0 :(得分:1)

首先我创建临时表,类似于你的:

File jarPath = new File(applicationPath);
        if (!jarPath.isDirectory()) {
            jarPath = jarPath.getParentFile();
        }

    File pkcs11wrapperFile = new File(jarPath, "libpkcs11wrapper" + arch + ".dll");
    System.out.println("Absolute path is "+pkcs11wrapperFile.getAbsolutePath());
    Pkcs11Shell pkcs11Shell = new Pkcs11Shell(pkcs11wrapperFile.getAbsolutePath());

然后我运行了动态SQL + UNPIVOT + PIVOT(关于透视,你可以阅读MSDNhere):

CREATE TABLE #tblmonth (
    id2 smallint,
    [year] varchar(50), 
    groups varchar(100), 
    element varchar(100), 
    [month] varchar(50), 
    budget decimal(18,2),
    actual decimal(18,2),
    variance decimal(18,2),
    [percent] decimal(18,2),
)

INSERT INTO #tblmonth VALUES
(1, 2016, 'CCARE', 'Basic', 'January', 52.28, 43.00, 43.98, 0.00),
(2, 2016, 'CCARE', 'Bonuses', 'January', 1.77, 17.10, -46.12, 0.00),
(3, 2016, 'CCARE', 'Overtime', 'January', 2.34, 20.20, 7.98, 0.00),
(4, 2016, 'CCARE', 'Comminication', 'January', 19.01, 27.34, -81.98, 0.00),
(5, 2016, 'CCARE', 'HDMF', 'January', 0.98, 22.17, -22.98, 0.00),
(1, 2016, 'CCARE', 'Basic', 'February', 152.28, 3.00, 4.98, 0.00),
(2, 2016, 'CCARE', 'Bonuses', 'February', 12.77, 1.10, -4.12, 0.00),
(3, 2016, 'CCARE', 'Overtime', 'February', 23.34, 3.20, 0.98, 0.00),
(4, 2016, 'CCARE', 'Comminication', 'February', 191.01, 2.34, -1.98, 0.00),
(5, 2016, 'CCARE', 'HDMF', 'February', 10.98, 2.17, -2.98, 0.00)

输出:

DECLARE @sql nvarchar(max),
        @columns nvarchar(max)
--here we get column names for pivoting, so we dont need to write them by hand
SELECT @columns = STUFF((
    SELECT ',budget'+[MONTH] + ',actual'+[MONTH]+ ',variance'+[MONTH]+',percent'+[MONTH]
    FROM #tblmonth 
    GROUP BY [MONTH]
    FOR XML PATH('')),1,1,'')

-- Main query, at first we UNPIVOT so we make column to rows,
-- then we pivot them back in a way we need.
SELECT @sql = '
SELECT *
FROM (
    SELECT  [year], 
            groups, 
            element, 
            [rows] + [month] as [rowname],
            [values]
    FROM (
        SELECT  id2,
                [year],
                groups,
                element,
                [month],
                CAST(budget as varchar(50)) as budget,
                CAST(actual as varchar(50)) as actual,
                CAST(variance as varchar(50)) as variance,
                CAST([percent] as varchar(50)) as [percent]
        FROM #tblmonth) as p
    UNPIVOT (
        [values] FOR [rows]
        IN (budget, actual, variance, [percent])
    ) as unpvt
    ) as p
PIVOT(
    MAX([values]) FOR [rowname] IN ('+@columns+'
)
)  as pvt'

EXEC sp_executesql @sql

答案 1 :(得分:1)

它应该是这样的:

 select 
   q.id2, q.year, q.groups, q.element, 
   jan.month as jMonth, jan.budget as jBudget, jan.actual as jActual, jan.variance as jVariance, jan.[percent] as jPercent, jan.date_update as jDateUpdate,
   feb.month as fMonth, feb.budget as fBudget, feb.actual as fActual, feb.variance as fVariance, feb.[percent] as fPercent, feb.date_update as fDateUpdate
 from (select groups, year, id2, element from tblmonth 
       where groups='CCARE' and year=2016 group by groups, year, id2, element) q
 left join (select * from tblmonth 
            where groups='CCARE' and year=2016 and month='January') jan
   on (q.groups = jan.groups and q.year = jan.year and 
       q.id2 = jan.id2 and q.element = jan.element)
 left join (select * from tblmonth 
            where groups='CCARE' and year=2016 and month='February') feb 
   on (q.groups = feb.groups and q.year = feb.year and 
       q.id2 = feb.id2 and q.element = feb.element);

只需在公共字段上加入子查询。

第一个子查询q并不是真正重要的。 因为您可以使用其中一个月来加入其他月份 但是如果要增加额外的月份,SQL会以这种方式看起来更好 虽然它会使SQL更小。例如:

select 
  jan.id2, jan.year, jan.groups, jan.element, 
  jan.month as jMonth, jan.budget as jBudget, jan.actual as jActual, jan.variance as jVariance, jan.[percent] as jPercent, jan.date_update as jDateUpdate,
  feb.month as fMonth, feb.budget as fBudget, feb.actual as fActual, feb.variance as fVariance, feb.[percent] as fPercent, feb.date_update as fDateUpdate
from tblmonth jan
left join tblmonth feb on (jan.groups = feb.groups and jan.year = feb.year and jan.id2 = feb.id2 
                           and jan.element = feb.element and feb.month = 'February')
where jan.groups='CCARE' and jan.year=2016 and jan.month='January';

答案 2 :(得分:1)

试试这个:

select t1.id2, t1.budget,t1.actual,t1.variance,t1[percent]
,t2.budget,t2.actual,t2.variance,t2.[percent] 
from tblmonth t1 inner join 
 (select * from tblmonth where groups='CCARE' and month='February' ) t2
 on t1.id2 = t2.id2 and t1.year = t2.year
 where t1.groups='CCARE' and t1.month='January'