Отключить с именем столбца в качестве даты - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть следующие данные в перекрестном формате:

prod_codigo  esps_fecini  day1    day2    day3    day4    day5  day6  day7
1077         2018-11-12   200.00  200.00  250.00  250.00  0.00  0.00  0.00
...

Мне нужно преобразовать данные во что-то вроде этого:

prod_codigo  esps_fecini   Bins
1077         2018-11-12    200.00
1077         2018-11-13    200.00
1077         2018-11-14    250.00
1077         2018-11-15    250.00
1077         2018-11-16    0.00
1077         2018-11-17    0.00
1077         2018-11-18    0.00
...

Как мне этого добиться?

Я использую следующий запрос, но не могу найти способ суммировать даты.Я использую SQL Server 2008

select prod_codigo,esps_fecini,U.Bins
from dba.estimprodsemana
unpivot
(
Bins
for datos in (esps_cadia1,esps_cadia2,esps_cadia3,esps_cadia4,esps_cadia5,esps_cadia6,esps_cadia7)
) U

Ответы [ 4 ]

0 голосов
/ 16 ноября 2018

Если у вас есть больше столбцов дня, чем вы хотите кодировать или указать, или если число столбцов дня является переменным, следующее «динамически» откроет ваши данные без фактического использования динамического SQL.

Очевидно, что UNPIVOT будет более производительным

Пример

declare @YourTable table (prod_codigo int,esps_fecini date,day1 decimal(5,2),day2 decimal(5,2),day3 decimal(5,2),day4 decimal(5,2),day5 decimal(5,2),day6 decimal(5,2),day7 decimal(5,2))
insert into @YourTable values
(1077,'20181112',200.00,200.00,250.00,250.00,0.00,0.00,0.00)


Select A.prod_codigo
      ,esps_fecini = dateadd(day,-1+replace(Item,'day',''),esps_fecini)
      ,Bins=C.Value
 From @YourTable A
 Cross Apply ( values (cast((Select A.* for XML RAW) as xml))) B(XMLData)
 Cross Apply (
                Select Item = a.value('local-name(.)','varchar(100)')
                      ,Value = a.value('.','decimal(5,2)') 
                 From  B.XMLData.nodes('/row')  as C1(n)
                 Cross Apply C1.n.nodes('./@*') as C2(a)
                 Where a.value('local-name(.)','varchar(100)') like  'day%'
             ) C

Возвращает

prod_codigo esps_fecini Bins
1077        2018-11-12  200.00
1077        2018-11-13  200.00
1077        2018-11-14  250.00
1077        2018-11-15  250.00
1077        2018-11-16  0.00
1077        2018-11-17  0.00
1077        2018-11-18  0.00
0 голосов
/ 16 ноября 2018

У вас был ответ на ваш вопрос, только небольшое форматирование:)

Кроме того, вам нужно получить смещение с помощью ROW_NUMBER (), основываясь на естественном порядке, в данном случае.Затем можно вычислить дату на основе применения производного поля на основе порядка столбцов D1..D7.

DECLARE @T TABLE(ID INT, Date DATETIME, D1 INT, D2 INT, D3 INT, D4 INT, D5 INT, D6 INT, D7 INT)
INSERT @T VALUES(1077,'11/12/2018',200,200,250,250,0,0,0)


SELECT
    ID,
    Date = DATEADD(DAY,DayNumber,Date),
    Bins    
FROM
(
    SELECT 
        ID,
        Date,
        Bins,
        DayNumber = ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ID) - 1
    FROM @T
    UNPIVOT
    (
        Bins FOR Dates in (D1,D2,D3,D4,D5,D6,D7)
    ) AS X
)AS Y
0 голосов
/ 16 ноября 2018

Если вы хотите unpivot для этого запроса, вы можете сделать это следующим образом:

declare @t table (prod_codigo int,esps_fecini date,day1 decimal(5,2),day2 decimal(5,2),
                  day3 decimal(5,2),day4 decimal(5,2),day5 decimal(5,2),day6 decimal(5,2),
                  day7 decimal(5,2))
insert into @t(prod_codigo,esps_fecini,day1,day2,day3,day4,day5,day6,day7) values
(1077,'20181112',200.00,200.00,250.00,250.00,0.00,0.00,0.00)

select
    prod_codigo,
    newDay,
    Value
from
    @t
        unpivot
    (Value for Offset in (day1,day2,day3,day4,day5,day6,day7)) u
        cross apply
    (select DATEADD(day,CONVERT(int,SUBSTRING(Offset,4,1))-1,esps_fecini) as newDay) v

Где мы сначала unpivot, а затем выясним, как извлечь полезное число из полученного данные (вместо метаданных - имена столбцов) для настройки значения даты.

Результат:

prod_codigo newDay     Value
----------- ---------- ---------------------------------------
1077        2018-11-12 200.00
1077        2018-11-13 200.00
1077        2018-11-14 250.00
1077        2018-11-15 250.00
1077        2018-11-16 0.00
1077        2018-11-17 0.00
1077        2018-11-18 0.00
0 голосов
/ 16 ноября 2018

Вы можете использовать APPLY вместо:

select e.prod_codigo, ee.*
from dba.estimprodsemana e cross apply
     ( values (esps_fecini, day1),
              (dateadd(day, 1, esps_fecini), day2),
              (dateadd(day, 2, esps_fecini), day3),
              (dateadd(day, 3, esps_fecini), day3),
              (dateadd(day, 4, esps_fecini), day4),
              (dateadd(day, 5, esps_fecini), day5),
              (dateadd(day, 6, esps_fecini), day6),
              (dateadd(day, 7, esps_fecini), day7)
     ) ee (esps_fecini, Bins);
...