Вывод динамического столбца запроса SQL Server select - PullRequest
0 голосов
/ 16 января 2019

Я хочу сделать следующее в SQL Server 2008

У меня есть таблица статей, подобная следующей

| ArticleId | Description |
|-----------+-------------|
|         1 | Test        |
|-----------+-------------|

И таблица прогноза заказа, как это.

| ArticleId | Week | Order | Amount |
|-----------+--------------+--------+
|         1 |   51 |     1 |      0 |
|         1 |   52 |     2 |    150 |
|         1 |    1 |     3 |      0 |
|         1 |    2 |     4 |    200 |
|         1 |    3 |     5 |      0 |
|-----------+------+-------+--------+

Есть ли способ создать запрос, который создает столбец для каждой записи в таблице прогнозов в порядке столбца order. Если это возможно, как я мог это сделать?

| ArticleId | Description | Week51 | Week52 | Week1 | Week2 | Week3 |
|-----------+-------------+-----------------+-------+-------+-------+
|         1 | Test        |     0  |    150 |     0 |   200 |     0 |
|-----------+-------------+--------+--------+-------+-------+-------+

Ответы [ 3 ]

0 голосов
/ 16 января 2019

Вы можете попробовать следующий запрос, используя Pivot для достижения желаемого результата.

Create Table Article (ArticleId Int, [Description] Varchar(10))
Insert Into Article Values (1, 'Test')

Create Table OrderForecast(ArticleId Int, [Week] Int, [Order] Int, Amount Int)
Insert Into OrderForecast Values (1, 51, 1, 0),(1, 52, 2, 150), (1, 1, 3, 0),(1, 2, 4, 200), (1, 3, 5,0)

Select ArticleId, [Description], Week51, Week52, Week1, Week2, Week3
from
(
  select ArticleId, [Description], Amount, [Week]
  from 
    (
    SELECT OrderForecast.ArticleId, 'Week' + Convert(Varchar(10), OrderForecast.[Week]) as [Week], [Order], Amount, 
        Article.[Description] as [Description] FROM OrderForecast
    Inner Join Article On OrderForecast.ArticleId = Article.ArticleId
    )a
) d
pivot
(
  max(Amount)
  for [Week] in (Week51, Week52, Week1, Week2, Week3)
) piv;

Результат будет таким, как показано ниже

ArticleId   Description Week51  Week52  Week1   Week2   Week3
-------------------------------------------------------------
1           Test        0       150     0       200     0

Здесь я использовал запрос в качестве таблицы, потому что неделя была в числах, таких как 1, 2, но вы хотите получить результат в неделю1, неделю2 и т. Д. Таким образом, я связал слово Неделя в числе и использовал его в запросе Pivot.

Вы можете найти живую демо Живая Демо Здесь

0 голосов
/ 16 января 2019

При условии, что номера НЕДЕЛИ и номера заказов совпадают, поддержание последовательности столбцов является небольшим делом.

Вы можете заметить, что я использовал #forecast и #article, потому что я не знал ваших реальных имен таблиц.

Пример

Declare @SQL varchar(max) = '
Select *
 From (
        Select A.ArticleID
              ,D.Description 
              ,B.*
         From  #forecast  A
         Join  #article   D on A.ArticleID=D.ArticleID
         Cross Apply (values (''Week''+left(Week,4),Amount) ) B(Item,Value)
      ) A
 Pivot (max([Value]) 
        For [Item] in (' + Stuff((Select ','+QuoteName('Week'+left(Week,4)) 
                                   From (Select Distinct top 100 [Order],Week From #forecast Order by [Order]  ) A  
                                   For XML Path('')),1,1,'') + ') ) p'
Exec(@SQL);
--Print @SQL

Возвращает

ArticleID   Description Week51  Week52  Week1   Week2   Week3
1           Test        0       150     0       200     0
0 голосов
/ 16 января 2019

В общем случае язык SQL строго требует, чтобы число и типы данных столбцов результата были известны во время компиляции запроса. То, о чем вы просите, не может быть известно до тех пор, пока план выполнения не будет подготовлен и вы не начнете искать данные.

Поэтому лучшее, что вы сможете сделать, - это выполнить три отдельных шага:

  1. Запустите запрос, чтобы сообщить вам о столбцах, которые вы хотите использовать.
  2. Используйте результаты # 1 для составления нового запроса на лету.
  3. Выполнить новый запрос и вернуть результаты

Даже в этом случае такой тип пивота лучше обрабатывается в вашем клиентском коде или инструменте отчетов. Единственная хорошая новость - все это возможно сделать с большинства платформ с помощью одной длинной строки SQL.

Для этой конкретной ситуации, когда вы четко просматриваете номера недель, вы можете обойти проблему, предполагая, что все 53 возможных недели вперед (не 52, из-за частичных недель в конце года!), И написание большого оператора SQL, который вручную учитывает все 55 столбцов (53 недели + статья и описание).

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