我有这个基本的数据库表,并且是SQL初学者。
+-------------+--------+----------+
| location | Week | Expenses |
+-------------+--------+----------+
| Backoffice | 201851 | 80 |
| frontoffice | 201852 | 110 |
| Backoffice | 201901 | 120 |
| Backoffice | 201902 | 70 |
| frontoffice | 201903 | 68 |
+-------------+--------+----------+
是否可以动态检索最近5周的结果,而不是每次都在我的数据透视表中对其进行硬编码?
这是我的代码:
SELECT * from
(SELECT[week]
,[Expenses]
from [cafe].[dbo].[table]where location = 'Backoffice'
) as Total_Expenses pivot (sum([expenses]) for [week] in ([201902],[201903],[201904],[201905],[201906],[201907],[201908],[201909])) as pivotable;
我希望能够只输入“ 5”,它向我显示最近5周。可能是通过“最大”公式”
答案 0 :(得分:3)
如果要选择前5周(最近几周),请使用TOP
:See here
SELECT TOP 5 *
FROM [cafe].[dbo].[table]
WHERE location = 'Backoffice'
ORDER BY Week Desc
将最后一行更改为ORDER BY Week [ ASC | DESC ]
,以更改顺序。
如果您想获得前5周的收入,并按周汇总费用(我假设您想按周和位置分组),请尝试以下操作:
select top (5) Location, Week, sum(Expenses)
FROM table_name
WHERE location = 'backoffice'
GROUP BY Week, Location
Order By Week Desc
P.S。我建议不要使用[table]作为您的表名。
答案 1 :(得分:2)
您正在寻找枢纽。我建议条件聚合:
SELECT SUM(CASE WHEN weeknum = 1 THEN expenses END) as week_1,
SUM(CASE WHEN weeknum = 2 THEN expenses END) as week_2,
SUM(CASE WHEN weeknum = 3 THEN expenses END) as week_3,
SUM(CASE WHEN weeknum = 4 THEN expenses END) as week_4,
SUM(CASE WHEN weeknum = 5 THEN expenses END) as week_5
FROM (SELECT t.*,
ROW_NUMBER() OVER (ORDER BY WEEK DESC) as weeknum
FROM [cafe].[dbo].[table] t
) t
WHERE location = 'Backoffice';
请注意,这会旋转值,但会为它们提供通用名称。如果您实际上要更改列的名称,则需要动态SQL。
答案 2 :(得分:1)
要处理可变数量的列(周),可以使用动态TSQL:
create table #tmp(location varchar(50), Week varchar(6),Expenses int)
insert into #tmp values
('Backoffice' ,'201851', 80),('frontoffice','201852',110),('Backoffice' ,'201901',120),('Backoffice' ,'201902', 70),('frontoffice','201903', 68)
declare @startDate date = '20190131' --Start date, probably you'll want to put Getdate() here
declare @weeks table ([weekNumber] nvarchar(4), [weekYear] nvarchar(4))
declare @weekCount int = 10 --numbers of weeks to show
declare @counter int = 0 --counter to loop on all weeks
declare @weekList varchar(max)='' --holds the list of dynamically generated column headers
declare @sql varchar(max)='' --holds the complete dynamical TSQL query
set @counter = @weekCount
while @counter > 0
begin
insert into @weeks
SELECT right('0' + cast(DATEPART(wk, DATEADD(WK,-(@counter),@startDate)) as varchar(2)),2)
, DATEPART(year, DATEADD(WK,-(@counter),@startDate))
set @counter = @counter - 1
end
select @weekList = @weekList + '[' + [weekYear] + [weekNumber] + '],' from @weeks
set @weekList = SUBSTRING(@weekList, 1, len(@weekList) - 1)
set @sql = @sql + ' SELECT * from'
set @sql = @sql + ' (SELECT[week]'
set @sql = @sql + ' ,[Expenses]'
set @sql = @sql + ' from #tmp where location = ''Backoffice'''
set @sql = @sql + ' ) as Total_Expenses pivot (sum([expenses]) for [week] in ('+@weekList+')) as pivotable;'
--execute dynamic query
exec(@sql)
输出为@weekCount = 5
:
输出为@weekCount = 10
: