Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 транспонировать таблицу  [new]
Lycan
Member

Откуда:
Сообщений: 6
Добрый Всем день!

Подскажите пожалуйста как можно решить следующею задачу.
На вход подаются две даты которые определяю диапазон выборки.
Далее данные собираются в такой табличный вид: data(год и месяц) -диапазоны даты могут изменяться, для краткости примера беру две

id | field1 | field2 | data
1 | A | A2 | 2010 09
1 | B | B2 | 2010 10
2 | C | C2 | 2010 09
2 | D | D2 | 2010 10

Нужен цикл который будет автоматически разворачивать эту таблицу в следующий вид

id | field1_201009 | field1_201010 | field2_201009 | field2_201010 |
1 | A B A2 B2
2 | C D C2 D
26 июл 12, 12:17    [12918775]     Ответить | Цитировать Сообщить модератору
 Re: транспонировать таблицу  [new]
tanglir
Member

Откуда:
Сообщений: 28966
Если дат конечное кол-во и они известны, можно впрямую написать запрос, используя sum(case when). Если нет - либо такой же запрос конструировать через prepared statements, либо транспонировать уже на клиенте.
26 июл 12, 12:37    [12918935]     Ответить | Цитировать Сообщить модератору
 Re: транспонировать таблицу  [new]
RXL
Member

Откуда:
Сообщений: 1599
У меня уже год в загашнике валяется статья о кросстабах для MySQL. Будет время, попробую на днях довести до читабельного вида.
26 июл 12, 13:15    [12919283]     Ответить | Цитировать Сообщить модератору
 Re: транспонировать таблицу  [new]
Lycan
Member

Откуда:
Сообщений: 6
tanglir, вы не могли бы поделиться парой ссылок с примерами кода?
28 июл 12, 21:11    [12929996]     Ответить | Цитировать Сообщить модератору
 Re: транспонировать таблицу  [new]
qwerty112
Guest
Lycan
tanglir, вы не могли бы поделиться парой ссылок с примерами кода?

вот прямо по sum(case when) и поищите - там 3-и страницы примеров ..
https://www.sql.ru/forum/actualthread.aspx?bid=6&tid=942876&hl=sum%20case
28 июл 12, 21:19    [12930004]     Ответить | Цитировать Сообщить модератору
 Re: транспонировать таблицу  [new]
Lycan
Member

Откуда:
Сообщений: 6
Подскажите плз, в чем ошибка? Получается как бы дублирование полей...

-- drop table tmps
set nocount on
create table tmps (id int, field1 varchar(max), field2 varchar(max), dat datetime)
INSERT INTO tmps VALUES (1, 'A','A2','20100901')
INSERT INTO tmps VALUES (1, 'B','B2','20101001')
INSERT INTO tmps VALUES (2, 'C','C2','20100901')
INSERT INTO tmps VALUES (2, 'D','D2','20101001')

-- select * from tmps
declare @s varchar(max)
set @s = null;

select @s = isnull(@s + 'isnull((case when convert(varchar,DAT,112) = ' + convert(varchar,DAT,112) + ' then field1 else null end), 0) [field1' +cast(dat as varchar(10)) +'],',
'isnull((case when convert(varchar,DAT,112) = ' + convert(varchar,DAT,112) + ' then field1 else null end), 0) [field1' +cast(dat as varchar(10)) +'],') +char(10)
from tmps;

select @s = 'select id,' + char(10) + stuff(@s, datalength(@s)-1, 1, '') + 'from tmps'

print @s
exec(@s)
29 июл 12, 00:40    [12930437]     Ответить | Цитировать Сообщить модератору
 Re: транспонировать таблицу  [new]
qwerty112
Guest
Lycan
Подскажите плз, в чем ошибка? Получается как бы дублирование полей...

-- drop table tmps
set nocount on
create table tmps (id int, field1 varchar(max), field2 varchar(max), dat datetime)
INSERT INTO tmps VALUES (1, 'A','A2','20100901')
INSERT INTO tmps VALUES (1, 'B','B2','20101001')
INSERT INTO tmps VALUES (2, 'C','C2','20100901')
INSERT INTO tmps VALUES (2, 'D','D2','20101001')

-- select * from tmps
declare @s varchar(max)
set @s = null;

select @s = isnull(@s + 'isnull((case when convert(varchar,DAT,112) = ' + convert(varchar,DAT,112) + ' then field1 else null end), 0) [field1' +cast(dat as varchar(10)) +'],',
'isnull((case when convert(varchar,DAT,112) = ' + convert(varchar,DAT,112) + ' then field1 else null end), 0) [field1' +cast(dat as varchar(10)) +'],') +char(10)
from tmps;

select @s = 'select id,' + char(10) + stuff(@s, datalength(@s)-1, 1, '') + 'from tmps'

print @s
exec(@s)

приехали ...

к концу 3-их суток, выяснилось что у ТС МС СКЛ )
29 июл 12, 08:33    [12930673]     Ответить | Цитировать Сообщить модератору
 Re: транспонировать таблицу  [new]
qwerty112
Guest
Lycan,

в МС СКЛ, для таких целей есть PIVOT

Модератор: Тема перенесена из форума "MySQL".


Сообщение было отредактировано: 29 июл 12, 11:17
29 июл 12, 08:37    [12930675]     Ответить | Цитировать Сообщить модератору
 Re: транспонировать таблицу  [new]
Lycan
Member

Откуда:
Сообщений: 6
qwerty112,

я вас не совсем понял, вроде вопрос задавал в ветке "Все форумы / Microsoft SQL Server" ???
То есть Dynamic SQL commands не подойдут для работы с MS SQL Server???
29 июл 12, 22:30    [12932102]     Ответить | Цитировать Сообщить модератору
 Re: транспонировать таблицу  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Есть такая мания, пихать всё-всё-всё в хранилище данных.
Вопрос, а в скуле какая версия OpenGL ща стоит?
30 июл 12, 03:08    [12932526]     Ответить | Цитировать Сообщить модератору
 Re: транспонировать таблицу  [new]
Lycan
Member

Откуда:
Сообщений: 6
Mnior,
у меня Microsoft SQL Server Management Studio 2008 V10.0.5500.0
как посмотреть версию OpenGL в SQL Management Studio?
30 июл 12, 11:08    [12933351]     Ответить | Цитировать Сообщить модератору
 Re: транспонировать таблицу  [new]
Yasha123
Member

Откуда:
Сообщений: 1837
(говнокод)
--drop table tmps
--create table tmps (id int, field1 varchar(max), field2 varchar(max), dat datetime)
--INSERT INTO tmps VALUES (1, 'A','A2','20100901') 
--INSERT INTO tmps VALUES (1, 'B','B2','20101001') 
--INSERT INTO tmps VALUES (2, 'C','C2','20100901') 
--INSERT INTO tmps VALUES (2, 'D','D2','20101001') 
--INSERT INTO tmps VALUES (1, 'AB','AB2','20101101') 
--INSERT INTO tmps VALUES (2, 'CD','CD2','20101101') 

declare @sql varchar(max), 
        @dat_list varchar(max),
        @cte varchar(max)
        
set @dat_list = ''


set @cte = ' 
;with cte as
(
select id, 
       case n when 1 then field1 when 2 then field2 end as field,
       case n when 1 then ''field1_''+ convert(char(8),dat, 112) 
              when 2 then ''field2_''+ convert(char(8),dat, 112) end as df
from tmps cross join (select 1 as n union all select 2)n
) '

select @dat_list = @dat_list +  ',[' + df + ']' 
from 
(
select distinct 
       case n when 1 then 'field1_'+ convert(char(8),dat, 112) 
              when 2 then 'field2_'+ convert(char(8),dat, 112) end as df
from tmps cross join (select 1 as n union all select 2)n
)t

set @dat_list = STUFF(@dat_list, 1, 1, '')
set @sql = @cte + 'select * from cte '
            + 'pivot (max(field) for df in (' 
            + @dat_list + '))p '
            
print @sql

exec (@sql)
30 июл 12, 13:22    [12934291]     Ответить | Цитировать Сообщить модератору
 Re: транспонировать таблицу  [new]
Lycan
Member

Откуда:
Сообщений: 6
Yasha123, огромное Вам спасибо! :)
Реализовываю для рабочей задачи, все работает.
30 июл 12, 16:45    [12935907]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить