Сводный SQL в этом случае?

#sql #sql-server #pivot

#sql #sql-сервер #сводный

Вопрос:

Я пытаюсь сделать это

 DATE             Insurance  Type    Billed  Rate
2/28/2011 0:00   BC/BS      INP     B       0.6383
2/28/2011 0:00   BC/BS      OUT     B       0.5216
2/28/2011 0:00   BC/BS      INP     U       0.1988
2/28/2011 0:00   BC/BS      OUT     U       0.3493
3/31/2011 0:00   BC/BS      INP     B       0.69
3/31/2011 0:00   BC/BS      OUT     B       0.6136
3/31/2011 0:00   BC/BS      INP     U       0.1877
3/31/2011 0:00   BC/BS      OUT     U       0.3567
  

Выглядит так

 Insurance   Type    Billed  2/28/2011 0:00  3/31/2011 0:00
BC/BS       INP     B       0.6383           0.69
BC/BS       OUT     B       0.5216           0.6136
BC/BS       INP     U       0.1988           0.1877
BC/BS       OUT     U       0.3493           0.3567
  

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

Заранее спасибо.

Ответ №1:

Если сводные столбцы (ваши даты) известны, вы можете использовать оператор PIVOT для получения ваших результатов:

 declare @t table (date datetime, Insurance varchar(10), Type char(3), Billed char(1), Rate decimal(10,4));

    insert into @t
        values  ('2/28/2011 0:00',   'BC/BS',      'INP',     'B',       '0.6383'),
                ('2/28/2011 0:00',   'BC/BS',      'OUT',     'B',       '0.5216'),
                ('2/28/2011 0:00',   'BC/BS',      'INP',     'U',       '0.1988'),
                ('2/28/2011 0:00',   'BC/BS',      'OUT',     'U',       '0.3493'),
                ('3/31/2011 0:00',   'BC/BS',      'INP',     'B',       '0.69'),
                ('3/31/2011 0:00',   'BC/BS',      'OUT',     'B',       '0.6136'),
                ('3/31/2011 0:00',   'BC/BS',      'INP',     'U',       '0.1877'),
                ('3/31/2011 0:00',   'BC/BS',      'OUT',     'U',       '0.3567')

    select  *
    from    (   select  [date] as pivot_col, 
                        Insurance, 
                        [Type], 
                        Billed, 
                        Rate 
                from    @t
            ) as d
    pivot   (   sum(Rate) for pivot_col in ([2/28/2011],[3/31/2011])
            ) as p;
  

Вероятно, вы не знаете значений, и если это так, вам нужно будет изучить возможность использования той же техники, но динамическим способом. Отличный пример здесь

Ответ №2:

На основе предоставленных вами примеров данных, я предполагаю, что у вас будет длинный список дат, которые вам нужно будет преобразовать в столбцы. Хотя вы можете использовать статическую сводную точку, как в другом ответе, вы можете использовать динамическую сводную точку, аналогичную приведенной ниже:

 DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ','   QUOTENAME(convert(char(10), date, 101)) 
                    from test
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query 
      = 'SELECT Insurance, [Type], Billed,'   @cols   ' from 
         (
            SELECT [date], 
               Insurance, 
               [Type], 
               Billed, 
               Rate 
            FROM test
         ) x
         pivot 
         (
            sum(Rate)
            for [date] in ('   @cols   ')
         ) p 
         order by billed'

execute(@query)
  

Смотрите SQL Fiddle с демонстрацией