Динамический SQL-запрос для возврата результатов в столбцах - PullRequest
0 голосов
/ 02 июля 2018

У меня есть эта базовая таблица базы данных, и я новичок в 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 недель. Может быть по "максимальной" формуле "

Ответы [ 3 ]

0 голосов
/ 02 июля 2018

Вы ищете пивот. Я бы предложил условную агрегацию:

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.

0 голосов
/ 02 июля 2018

Для обработки переменного количества столбцов (недель) вы можете использовать динамический 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:

enter image description here

Вывод с @weekCount = 10:

enter image description here

0 голосов
/ 02 июля 2018

Если вы хотите выбрать первые 5 недель (самые последние недели), используйте TOP: См. Здесь

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

SQL Fiddle

P.S. Я бы порекомендовал не использовать [table], так как имя вашей таблицы .

...