Как преобразовать данные строки в имя столбца? - PullRequest
1 голос
/ 03 мая 2019

У меня есть некоторые данные по дате, и мне нужно суммировать по месяцам.Я думаю, что я могу использовать функцию PIVOT в SQL Server 2012, но я не могу понять это правильно.

Для простоты цели таблицы называются подробности и сводка, детали имеют количество посетителей по месяцам и воротам.Сводная таблица имеет Gate, тип посетителя и 12 столбцов для каждого месяца.

DECLARE @tblDetails TABLE (
    Gate varchar(15), EOM Date, TotVisitors decimal(10,2), TotKids decimal(10,2)
);

DECLARE @tblSumm TABLE (
    Gate varchar(15), CatDesc varchar(50),
    Jan decimal(10,2), Feb decimal(10,2), Mar decimal(10,2), 
    Apr decimal(10,2), May decimal(10,2), Jun decimal(10,2),
    Jul decimal(10,2), Aug decimal(10,2), Sep decimal(10,2), 
    Oct decimal(10,2), Nov decimal(10,2), Dec decimal(10,2)
);
insert into @tblDetails select 'East', '1/31/2018', 1000, 350
insert into @tblDetails select 'East', '2/28/2018', 990,225
insert into @tblDetails select 'East', '3/31/2018', 970, 390
insert into @tblDetails select 'East', '4/30/2018', 977, 290
insert into @tblDetails select 'East', '5/31/2018', 960, 375
insert into @tblDetails select 'East', '6/30/2018', 1020, 425
insert into @tblDetails select 'East', '7/31/2018', 1117, 450
insert into @tblDetails select 'East', '8/31/2018', 1090, 443
insert into @tblDetails select 'East', '9/30/2018', 980, 210
insert into @tblDetails select 'East', '10/31/2018', 960, 190
insert into @tblDetails select 'East', '11/30/2018', 990, 195
insert into @tblDetails select 'East', '12/31/2018', 1020, 330

insert into @tblDetails select 'West', '1/31/2018', 992, 333
insert into @tblDetails select 'West', '2/28/2018', 980, 265
insert into @tblDetails select 'West', '3/31/2018', 1005, 397
insert into @tblDetails select 'West', '4/30/2018', 960, 265
insert into @tblDetails select 'West', '5/31/2018', 982, 344
insert into @tblDetails select 'West', '6/30/2018', 1017, 399
insert into @tblDetails select 'West', '7/31/2018', 1080, 442
insert into @tblDetails select 'West', '8/31/2018', 1045, 413
insert into @tblDetails select 'West', '9/30/2018', 940, 217
insert into @tblDetails select 'West', '10/31/2018', 925, 302
insert into @tblDetails select 'West', '11/30/2018', 937, 287
insert into @tblDetails select 'West', '12/31/2018', 958, 271

insert into @tblDetails select 'North', '5/31/2018', 780, 380
insert into @tblDetails select 'North', '6/30/2018', 810, 400
insert into @tblDetails select 'North', '7/31/2018', 835, 411
insert into @tblDetails select 'North', '8/31/2018', 809, 415
insert into @tblDetails select 'North', '9/30/2018', 730, 390

insert into @tblDetails select 'South', '1/31/2018', 630, 210
insert into @tblDetails select 'South', '2/28/2018', 550, 190
insert into @tblDetails select 'South', '3/31/2018', 607, 215

Это то, что я хочу в моей сводной таблице:

Gate    CatDesc Jan Feb Mar Apr May     Jun July    Aug Sep Oct Nov Dec
East    Number of Visitors  1000    990 970 977 960 1020    1117    1090    980 960 990 1020
East    Number of Children  350 225 390 290 375 425 450 443 210 190 195 330
East    % of Children   35.00   22.73   40.21   29.68   39.06   41.67   40.29   40.64   21.43   19.79   19.70   32.35
West    Number of Visitors  992 980 1005    960 982 1017    1080    1045    940 925 937 958
West    Number of Children  333 265 397 265 344 399 442 413 217 302 287 271
West    % of Children   33.57   27.04   39.50   27.60   35.03   39.23   40.93   39.52   23.09   32.65   30.63   28.29
North   Number of Visitors  0   0   0   0   0   810 835 809 730 0   0   0
North   Number of Children  0   0   0   0   0   400 411 415 390 0   0   0
North   % of Children   0   0   0   0   0   49.38   49.22   51.30   53.42   0   0   0
South   Number of Visitors  630 550 607 0   0   0   0   0   0   0   0   0
South   Number of Children  210 190 215 0   0   0   0   0   0   0   0   0
South   % of Children   33.33   34.55   35.42   0   0   0   0   0   0   0   0   0

1 Ответ

2 голосов
/ 03 мая 2019

Лично я предпочитаю использовать в качестве кросс-таблицы, чем оператор PIVOT. Вам нужно использовать предложение VALUES, чтобы получить описание, а затем использовать кросс-таблицу для получения значений:

DECLARE @Year int = 2018;

SELECT D.Gate,
       V.CatDesc,
       ISNULL(MAX(CASE WHEN D.EOM = EOMONTH(DATEFROMPARTS(@Year, 1,1)) THEN V.KPI END),0) AS [Jan],
       ISNULL(MAX(CASE WHEN D.EOM = EOMONTH(DATEFROMPARTS(@Year, 2,1)) THEN V.KPI END),0) AS [Feb],
       ISNULL(MAX(CASE WHEN D.EOM = EOMONTH(DATEFROMPARTS(@Year, 3,1)) THEN V.KPI END),0) AS [Mar],
       ISNULL(MAX(CASE WHEN D.EOM = EOMONTH(DATEFROMPARTS(@Year, 4,1)) THEN V.KPI END),0) AS [Apr],
       ISNULL(MAX(CASE WHEN D.EOM = EOMONTH(DATEFROMPARTS(@Year, 5,1)) THEN V.KPI END),0) AS [May],
       ISNULL(MAX(CASE WHEN D.EOM = EOMONTH(DATEFROMPARTS(@Year, 6,1)) THEN V.KPI END),0) AS [Jun],
       ISNULL(MAX(CASE WHEN D.EOM = EOMONTH(DATEFROMPARTS(@Year, 7,1)) THEN V.KPI END),0) AS [Jul],
       ISNULL(MAX(CASE WHEN D.EOM = EOMONTH(DATEFROMPARTS(@Year, 8,1)) THEN V.KPI END),0) AS [Aug],
       ISNULL(MAX(CASE WHEN D.EOM = EOMONTH(DATEFROMPARTS(@Year, 9,1)) THEN V.KPI END),0) AS [Sep],
       ISNULL(MAX(CASE WHEN D.EOM = EOMONTH(DATEFROMPARTS(@Year, 10,1)) THEN V.KPI END),0) AS [Oct],
       ISNULL(MAX(CASE WHEN D.EOM = EOMONTH(DATEFROMPARTS(@Year, 11,1)) THEN V.KPI END),0) AS [Nov],
       ISNULL(MAX(CASE WHEN D.EOM = EOMONTH(DATEFROMPARTS(@Year, 12,1)) THEN V.KPI END),0) AS [Dec]
FROM @tblDetails D                                                                     
     CROSS APPLY(VALUES(1,'Number of Visitors',D.TotVisitors),
                       (2,'Number of Children',D.TotKids),
                       (3,'% of Children',CONVERT(decimal(8,2),D.TotKids / (D.TotVisitors *1.0)*100)))V(Ordering,CatDesc,KPI)
GROUP BY D.Gate,
         V.CatDesc,
         V.Ordering
ORDER BY D.Gate,
         V.Ordering;

Обратите внимание, что столбец в SQL Server может иметь только один тип данных, поэтому все возвращаемые значения: decimal(8,2).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...