Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Составление SQL-запросов > t-sql запрос по таблице


Автор: IrinaLive 7.4.2013, 21:16
Здравствуйте, помогите, пожалуйста, в составлении запроса, никак не получается.
Есть таблица вида:

Id    KorId       LowerDate       UpperDate       RFM_Code
1        1            2010-08-09    2011-08-09            123
2        2            2010-08-09    2011-08-09        321
3        3            2010-08-09    2011-08-09        125
4        4            2010-08-09    2011-08-09        252
5        1            2011-08-09    2012-08-09            235
6        2           2011-08-09     2012-08-09            523
7        3            2011-08-09    2012-08-09            425
8        4            2011-08-09    2012-08-09            421

Можно ли как-то привести эти записи примерно к такому виду:

KorId        2010-08-09/2011-08-09          2011-08-09/2012-08-09
1                       123                                                235
2                       321                                                523
3                       125                                                425
4                       252                                                421    
                                    

Автор: Arantir 7.4.2013, 22:15
Просто сделайте подзапрос наряду с указанием полей и задайте ему алиас.

Код

SELECT 
        `KorId` as _KorId, 
        (SELECT `RFM_Code` FROM `table` WHERE `LowerDate` = '2010-08-09' AND `UpperDate` = '2011-08-09' AND `KorId` = _KorId LIMIT 1) as '2010-08-09/2011-08-09', 
        (SELECT `RFM_Code` FROM `table` WHERE `LowerDate` = '2011-08-09' AND `UpperDate` = '2012-08-09' AND `KorId` = _KorId LIMIT 1) as '2011-08-09/2012-08-09' 
    FROM `table` GROUP BY `KorId`;

Автор: IrinaLive 7.4.2013, 23:10
Спасибо.

Но таблица гораздо больше, чем тот фрагмент, что я привела, и интервалов времени тоже.

Цитата

Код

(SELECT `RFM_Code` FROM `table` WHERE `LowerDate` = '2010-08-09' AND `UpperDate` = '2011-08-09' AND `KorId` = _KorId LIMIT 1) as '2010-08-09/2011-08-09'



Перебирать все подобным образом не удобно, потому что не всегда есть возможность узнать сколько временных интервалов (типа 2010-08-09/2011-08-09) вообще

Автор: Akina 8.4.2013, 07:56
Цитата(IrinaLive @  8.4.2013,  00:10 Найти цитируемый пост)
не всегда есть возможность узнать сколько временных интервалов (типа 2010-08-09/2011-08-09) вообще

1) Должна существовать таблица таких интервалов;
2) Используемая СУБД должна поддерживать использование перекрёстных запросов (либо придётся использовать динамический SQL).

Автор: FINANSIST 8.4.2013, 09:51
 скормить запрос функции Transform субд Access - там вообще неважно, сколько столбцов на входе

Автор: Akina 8.4.2013, 09:54
Хм... а кто сказал, что речь идёт об Access? 

Автор: IrinaLive 8.4.2013, 10:07
Речь идет о MS SQL Server.

Я просто думала, что можно подобное сделать с помощью JOIN.

Автор: Akina 8.4.2013, 10:15
Цитата(IrinaLive @  8.4.2013,  11:07 Найти цитируемый пост)
Речь идет о MS SQL Server.

http://msdn.microsoft.com/en-us/library/ms177410(v=SQL.105).aspx

Автор: IrinaLive 8.4.2013, 11:53
я так поняла мне нужен динамический PIVOT, но он используется вроде с использованием агрегатных функций, мне они не нужны. 

Если вас не затруднит, не могли бы вы набросать примерный запрос, пожалуйста

Автор: Akina 8.4.2013, 12:13
Цитата(IrinaLive @  8.4.2013,  12:53 Найти цитируемый пост)
я так поняла мне нужен динамический PIVOT, но он используется вроде с использованием агрегатных функций, мне они не нужны. 

Вы поняли неверно.
Если перевод для Вас сложен - прочитайте встроенную справку по пперекрёстным запросам MS Access и по сводным таблицам (самые основы) MS Excel.

Автор: FINANSIST 8.4.2013, 12:29
Цитата(Akina @  8.4.2013,  09:54 Найти цитируемый пост)
Хм... а кто сказал, что речь идёт об Access? 

на момент ответа относительно субд вообще никто ничего не сказал.


Цитата(IrinaLive @  8.4.2013,  10:07 Найти цитируемый пост)
Речь идет о MS SQL Server.

ну, тогда как-то так:
Код

with a1 as
(select 'A' as tp, 1 as mnth, 1 as vl
union all
select 'A' as tp, 1 as mnth, 2 as vl
union all
select 'B' as tp, 2 as mnth, 1 as vl
union all
select 'С' as tp, 3 as mnth, 1 as vl)
-----------------------------------------------------------------
select tp, coalesce([1],0) as [1], coalesce([2],0) as [2], coalesce([3],0) as [3] from
(select tp,[1],[2],[3]  from (select tp, mnth, vl  from a1 ) a2
pivot (sum(vl) for mnth in ([1],[2],[3]))as pitab
)a3

опять же грабли в неуниверсальности - надо заранее знать количество столбцов, Access в этом плане гибче.
А вообще IrinaLive,  это простейшая задача для OLAP/Pivot tables 

Автор: Akina 8.4.2013, 12:37
Цитата(FINANSIST @  8.4.2013,  13:29 Найти цитируемый пост)
на момент ответа относительно субд вообще никто ничего не сказал.

Угу... но просмотр профиля ТС позволял с высокой долей вероятности предполагать, что 
Цитата(IrinaLive @  8.4.2013,  11:07 Найти цитируемый пост)
Речь идет о MS SQL Server.


Автор: IrinaLive 8.4.2013, 15:33
Большое спасибо за помощь!


Думаю, скорее всего не рационально, но сделала следующим образом:

Код

        DECLARE @columns VARCHAR(8000)

        SELECT @columns = COALESCE(@columns + ',[' +  CAST([LowerDate] AS VARCHAR)+ '  ' + CAST([UpperDate] AS VARCHAR) + ']' ,
                            '[' + CAST([LowerDate] AS VARCHAR)+ '  ' + CAST([UpperDate] AS VARCHAR)+ ']')
        FROM  table 
        GROUP BY [UpperDate],[LowerDate] 

        DECLARE @query NVARCHAR(MAX)
                

        SET @query = 'select * from (select 
        [KorId], CAST([LowerDate] AS VARCHAR)'+ '+''  ''+' +'CAST([UpperDate] AS VARCHAR)  as col ,[RFM_Code] from table 
        )AS SourceTable
        Pivot(SUM(RFM_Code) for col IN ('+@columns+' ) ) AS PVT ORDER BY KorId;'

        EXECUTE SP_EXECUTESQL @query


Вроде работает.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)