我正在尝试设置一个从表中选择多行的查询,并将类似的行组合成一个包含多列的行。我相信我可以通过枢轴来做到这一点但是每一行都不会有相同数量的列,这就是我遇到问题的地方。我在下面举例说明了我的意思。
此:
Account Period Amount
01 0001 1111
01 0002 2222
01 0003 3333
02 0001 1111
03 0001 1111
04 0001 1111
04 0002 2222
应该来这个:
Account 0001 0002 0003
01 1111 2222 3333
02 1111
03 1111
04 1111 2222
这是我的初始查询,它将所有数据拉到一起:
WITH CTE AS(
SELECT
a.Period, a.Account, SUM(a.Amount) Amount
FROM
LedgerAP a
WHERE
a.Period >= 201500
GROUP BY a.Period, a.Account
UNION
SELECT
b.Period, b.Account, SUM(b.Amount) Amount
FROM
LedgerAR b
WHERE
b.Period >= 201500
GROUP BY b.Period, b.Account
UNION
SELECT
c.Period, c.Account, SUM(c.Amount)
FROM
LedgerEx c
WHERE
c.Period >= 201500
GROUP BY c.Period, c.Account
UNION
SELECT
d.Period, d.Account, SUM(d.Amount)
FROM
LedgerMisc d
WHERE
d.Period >= 201500
GROUP BY d.Period, d.Account
)
SELECT account,
max(case when period = @Budgetyear + '01' then SUM(amount) end) Amount1,
max(case when period = @Budgetyear + '02' then SUM(amount) end) Amount2,
max(case when period = @Budgetyear + '03' then SUM(amount) end) Amount3,
max(case when period = @Budgetyear + '04' then SUM(amount) end) Amount4,
max(case when period = @Budgetyear + '05' then SUM(amount) end) Amount5,
max(case when period = @Budgetyear + '06' then SUM(amount) end) Amount6,
max(case when period = @Budgetyear + '07' then SUM(amount) end) Amount7,
max(case when period = @Budgetyear + '08' then SUM(amount) end) Amount8,
max(case when period = @Budgetyear + '09' then SUM(amount) end) Amount9,
max(case when period = @Budgetyear + '10' then SUM(amount) end) Amount10,
max(case when period = @Budgetyear + '11' then SUM(amount) end) Amount11,
max(case when period = @Budgetyear + '12' then SUM(amount) end) Amount12
FROM CTE
GROUP BY account
ORDER BY account ASC
现在我怎样才能像上面所示那样组织这个?任何帮助都会很棒!
答案 0 :(得分:0)
归功于@Bluefeet's solution here,你可以建立这样的动态角色:
create table table1 (Account varchar(2), Period varchar(4), Amount int)
insert into table1 values
('01', '0001', 1111),
('01', '0002', 2222),
('01', '0003', 3333),
('02', '0001', 1111),
('03', '0001', 1111),
('04', '0001', 1111),
('04', '0002', 2222);
动态查询:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(t.period)
FROM table1 t
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT Account, ' + @cols + ' from
(
select Account
, Period
, Amount
from table1
) x
pivot
(
max(amount)
for period in (' + @cols + ')
) p '
execute(@query)
GO
<强>结果:强>
+---------+------+--------+--------+
| Account | 0001 | 0002 | 0003 |
+---------+------+--------+--------+
| 01 | 1111 | 2222 | 3333 |
| 02 | 1111 | (null) | (null) |
| 03 | 1111 | (null) | (null) |
| 04 | 1111 | 2222 | (null) |
+---------+------+--------+--------+
答案 1 :(得分:-1)
您的基本支点:
SELECT
SUM(case Period when '0001' then Amount end) as '0001',
SUM(case Period when '0002' then Amount end) as '0002',
SUM(case Period when '0003' then Amount end) as '0003'
FROM LedgerAP
GROUP BY Account
动态创建该查询,如果您有许多Period:
值,这将非常有用DECLARE @SQL varchar(max) = 'SELECT '
;WITH Periods AS
(
SELECT DISTINCT Period
FROM LedgerAP
)
SELECT @SQL = @SQL +
'SUM(case Period when ''' + Period + ''' then Amount end) as ''' + Period + ''','
SET @SQL = LEFT(@SQL,LEN(@SQL) - 1) + ' FROM LedgerAP GROUP BY Account'
EXEC(@SQL)