SQL Как повернуть эту таблицу? - PullRequest
0 голосов
/ 06 февраля 2020

Мне очень трудно понять, как что-то поворачивать.

У меня есть этот простой запрос

select 
year
,AVG(Quantity) Quantity
,AVG(Price) Price
,CAST(Datepart(wk,Date) as nvarchar) + '-' + RIGHT(CAST(year(Date) as NVARCHAR),2) Week
from Yearly
GROUP BY Year, CAST(Datepart(wk,Date) as nvarchar) + '-' + RIGHT(CAST(year(Date) as NVARCHAR),2)

Что приводит к этой таблице

+------+----------+---------------+------+
| year | Quantity |     Price     | Week |
+------+----------+---------------+------+
| 16   |   877814 | 68636081.39   | 6-20 |
| 17   |   436029 | 2635873.72    | 6-20 |
| 18   |  3793464 | 65971353.61   | 6-20 |
| 19   | 23552519 | 478741292.122 | 6-20 |
| 20   |  6973687 | 34658140.815  | 6-20 |
| Z01  |  7776508 | 54949609.221  | 6-20 |
+------+----------+---------------+------+

Сейчас у меня есть только одна неделя, но как дни go у меня есть работа, которая будет собирать эти 6 строк для 7-20, 8-20, 9-20 и т. д. c.

Я хочу, чтобы мой стол выглядел как

+------+--------+-------------+--------+------------+---------+-------------+----------+-------------+---------+-------------+---------+-------------+----------+-------------+
|      |   16                 |   17                |   18                  |    19                  |   20                  |   Z01                 |  Total   |             |
+------+--------+-------------+--------+------------+---------+-------------+----------+-------------+---------+-------------+---------+-------------+----------+-------------+
| Week | Qty    | Price       | Qty    | Price      | Qty     | Price       | Qty      | Price       | Qty     | Price       | Qty     | Price       | Qty      | Price       |
| 6-20 | 877814 | 68636081.39 | 436029 | 2635873.72 | 3793464 | 65971353.61 | 23552519 | 478741292.1 | 6973687 | 34658140.82 | 7776508 | 54949609.22 | 43410021 | 705592350.9 |
| 7-20 |        |             |        |            |         |             |          |             |         |             |         |             |          |             |
| 8-20 |        |             |        |            |         |             |          |             |         |             |         |             |          |             |
+------+--------+-------------+--------+------------+---------+-------------+----------+-------------+---------+-------------+---------+-------------+----------+-------------+

Должен ли я использовать Pivot или есть лучший способ сделать это? Если

Ответы [ 3 ]

1 голос
/ 06 февраля 2020

Это вариант ответа pwilcox, но более краткий:

select v.week,
       avg(case when year = 16 then quantity end) as quantityYr16,
       avg(case when year = 16 then price end) as priceYr16,
       avg(case when year = 17 then quantity end) as quantityYr17,
       avg(case when year = 17 then price end) as priceYr17,
       . . .
       sum(quantity) as totalQuantity,
       sum(price) as totalPrice
from yearly cross apply
     (values (concat(datename(week, date), '-', datename(year, date)))
     ) v(week)
group by v.week
order by v.week;

Примечания:

  • Никогда не используйте varchar() без длины. Длина по умолчанию варьируется в зависимости от контекста и может быть недостаточно длинной.
  • datename() - это удобная функция, которая возвращает строки, а не числа.
  • При использовании функций части даты укажите полное названия частей даты - week, year. Это облегчает чтение кода.
0 голосов
/ 06 февраля 2020

Вот ПИВОТ. Предполагается, что вам не нужны Dynami c

Пример

Select *
 From  ( 
        Select A.Week
              ,B.* 
         From  (
                  -- YOUR ORIGINAL QUERY HERE (without the Order By) --- 
               ) A
         Cross Apply ( values (concat(year,'_Qty')  ,[Quantity])
                             ,(concat(year,'_Price'),[Price])
                             ,(concat('Total','_Qty'),[Quantity])
                             ,(concat('Total','_Price'),[Price])
                     ) B(item,value) 
       ) src
 Pivot (sum(Value) for Item in ([16_Qty],[16_Price],[17_Qty],[17_Price],[18_Qty],[18_Price],[19_Qty],[19_Price],[20_Qty],[20_Price],[Z01_Qty],[Z01_Price],[Total_Qty],[Total_Price]) ) pvt 

Возвраты

enter image description here

0 голосов
/ 06 февраля 2020

Для многостолбцовой сводной системы того типа, который вам нужен, вам придется воспользоваться тем, что агрегатные операции не учитывают нулевые значения. Поэтому поместите выписки в свои средние значения, которые дают количество или цену, если они связаны с каким-либо конкретным годом, и ноль в противном случае.

select      ap.week,
            quantityYr16 = avg(case when year = 16 then quantity end),
            priceYr16 = avg(case when year = 16 then price end),
            quantityYr17 = avg(case when year = 17 then quantity end),
            priceYr17 = avg(case when year = 17 then price end),
            ...
from        yearly
cross apply (select week = 
                cast(datepart(wk,date) as nvarchar) + '-' + 
                right(cast(year(date) as nvarchar),2)
            ) ap
group by    ap.week

Однако эта структура предназначена для отчетности. SQL не обрабатывает это, а также инструменты отчетности, такие как HTML, SSRS или Excel. Я бы выполнил эту операцию с помощью любого инструмента отчетности, которым вы в конечном итоге сообщите об этом.

...