2013-11-25 5 views
0

Я пытаюсь создать сводную таблицу в sql, но у меня возникают трудности. Вот моя проблема: у меня есть столбец в моей базе данных под названием «statusreason», и мне нужно предоставить сумму каждого statusreason за последнюю неделю. Мой набор выглядит следующим образом:Создание сводной таблицы с использованием sql

StatusReason Count

мне нужно повернуть эту таблицу так, что она выглядит как следующее:

enter image description here

Есть целый ряд statusreasons, которые не представлены в выше таблицы, так как они не происходили на прошлой неделе.

Запрос используется для создания результирующего набора:

select inv.statusreason 
    , count(inv.statusreason) as 'StatusCount' 
from invoicetbl inv (nolock) 
inner join trucktbl tru (nolock) on inv.tru_key = tru.tru_key 
where inv.client_key = 123 
    and inv.createdate > getdate() - 7 
group by inv.statusreason 

Если этого не достаточно информации, пожалуйста, посоветуйте, что я мог бы добавить, чтобы улучшить этот вопрос.

Благодарим за любую помощь, которую вы можете предоставить.

+2

Какие СУБД? SQL Server, Oracle и т. Д. – dazedandconfused

+0

SQL Server. Благодаря! Если мне нужно добавить больше, пожалуйста, дайте мне знать. –

+0

Вы знаете причины статуса раньше времени? Или это будет определено во время выполнения? – Taryn

ответ

2

Поскольку вы хотите преобразовать свои строки данных в столбцы, вам нужно PIVOT данных. Это можно сделать несколькими способами.

Если у вас есть ограниченное количество значений, которые вы собираетесь возвращаться, то вы можете использовать агрегатную функцию с выражением CASE-:

select 
    count(case when statusreason = 181 then 1 end) [181], 
    count(case when statusreason = 20 then 1 end) [20], 
    count(case when statusreason = 212 then 1 end) [212], 
    count(case when statusreason = 232 then 1 end) [232] 
from 
(
    select inv.statusreason 
    from invoicetbl inv (nolock) 
    inner join trucktbl tru (nolock) 
     on inv.tru_key = tru.tru_key 
    where inv.client_key = 123 
     and inv.createdate > getdate() - 7 
) d; 

Или вы можете использовать функцию PIVOT:

select [181], [20], [212], [232] 
from 
(
    select inv.statusreason 
    from invoicetbl inv (nolock) 
    inner join trucktbl tru (nolock) 
     on inv.tru_key = tru.tru_key 
    where inv.client_key = 123 
     and inv.createdate > getdate() - 7 
) d 
pivot 
(
    count(statusreason) 
    for statusreason in ([181], [20], [212], [232]) 
) p; 

Если у вас есть неизвестное количество значений, которые будут возвращены, вам нужно будет использовать динамический SQL. Это создает строку sql, которая затем будет выполнена.

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(statusreasons) 
        from statusreasontbl 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT ' + @cols + ' 
      from 
      (
       select inv.statusreason 
       from invoicetbl inv (nolock) 
       inner join trucktbl tru (nolock) 
        on inv.tru_key = tru.tru_key 
       where inv.client_key = 123 
        and inv.createdate > getdate() - 7 
      ) x 
      pivot 
      (
       count(statusreason) 
       for statusreason in (' + @cols + ') 
      ) p ' 

execute sp_executesql @query; 
+0

Спасибо @bluefeet! Это сработало отлично. Основанием было то, что я пытался делать все утро, но ваш пример указал на то, что я ошибался. –

Смежные вопросы