Сводной запрос перекрестной таблицы SQL

У меня есть таблица, как показано ниже.

CaseID   StatusID    StageID     CaseRegisterTime   City
1        1            5            datetime         XYZ
2        1            5            datetime         ABC

Теперь я хочу его Citywise считать и только для определенных дат, а также в условии для statusid = 1 и stageid = 5.

Cities     CurrentDate-1    CurrentDate-2   January2012-CurrentDate-3
XYZ           5                  51                  5008
JUS           0                   0                   125
ABC           1                   0                   48

Я хочу, чтобы мой заголовок группировал случаи для CaseRegisterTime, как показано выше.

Пожалуйста помоги.


person k-s    schedule 22.03.2012    source источник
comment
попробуйте погуглить запросы сводной таблицы sql, вы найдете множество примеров того, что вы пытаетесь сделать.   -  person Brian    schedule 22.03.2012
comment
Я попытался выполнить поворот, но основная проблема заключается в столбце даты, который я только ограничил, как показано в приведенном выше примере вывода для ограниченных дат, и не хочу искать все другие даты.   -  person k-s    schedule 22.03.2012
comment
Откуда вы берете даты? И вообще, когда мы спрашиваем, что вы пробовали? мы хотим видеть код   -  person Adriano Carneiro    schedule 22.03.2012
comment
@Keyur, пожалуйста, предоставьте более значимые данные (даже если они фальшивые) ... очень сложно понять, откуда берутся желаемые результаты. Являются ли эти столбцы CurrentDate подсчетами, суммами или чем-то еще?   -  person Tim Lehner    schedule 22.03.2012
comment
@Brian Просто Google это бесполезно .. поскольку, когда другие выполняют поиск в Google, они постоянно получают результаты, в которых говорится, что это просто Google. Вызывает неприятную рекурсию.   -  person Volvox    schedule 16.03.2013


Ответы (3)


Используйте case when, чтобы преобразовать интересующие вас даты в 'CurrentDate-1' и 'CurrentDate-2', а затем сведите результаты, используя эти строки в качестве новых столбцов.

В качестве альтернативы вы можете сделать что-то вроде этого:

select City, sum(Date1) as Date1, sum(Date2) as Date2
from(
select City, 
    case when CaseRegisterTime='2012-01-01' then 1 else 0 end as Date1,
    case when  CaseRegisterTime='2012-15-01' then 1 else 0 end as Date2
from sample
) as T
group by City

вам также придется отфильтровать регистры, которые не имеют желаемой даты.

person JotaBe    schedule 22.03.2012

Вот один из многих способов сделать это в SQL Server 2008 (используя тип данных Date):

select distinct a.City as Cities
    , (select count(*)
        from MyTable
        where CaseRegisterTime >= cast(getdate() - 1 as date)
            and CaseRegisterTime < cast(getdate() - 0 as date)
            and StatusID = a.StatusID
            and StageID = a.StageID
            and City = a.City
    ) as [CurrentDate-1]
    , (select count(*)
        from MyTable
        where CaseRegisterTime >= cast(getdate() - 2 as date)
            and CaseRegisterTime < cast(getdate() - 1 as date)
            and StatusID = a.StatusID
            and StageID = a.StageID
            and City = a.City
    ) as [CurrentDate-2]
    , (select count(*)
        from MyTable
        where CaseRegisterTime >= cast('20120101' as date)
            and CaseRegisterTime < cast(getdate() - 2 as date)
            and StatusID = a.StatusID
            and StageID = a.StageID
            and City = a.City
    ) as [January2012-CurrentDate-3]
from MyTable a
where a.StatusID = 1
    and a.StageID = 5

Обновить

Метод case и sum, который использует @JotaBe, примерно в два раза быстрее на моей машине (с гораздо меньшим количеством сканирований и чтений), так что вот как это может выглядеть:

select a.City as Cities
    , sum(a.[CurrentDate-1]) as [CurrentDate-1]
    , sum(a.[CurrentDate-2]) as [CurrentDate-2]
    , sum(a.[January2012-CurrentDate-3]) as [January2012-CurrentDate-3]
from (
    select City
        , case when CaseRegisterTime >= cast(getdate() - 1 as date)
                and CaseRegisterTime < cast(getdate() - 0 as date)
                then 1 else 0 end [CurrentDate-1]
        , case when CaseRegisterTime >= cast(getdate() - 2 as date)
                and CaseRegisterTime < cast(getdate() - 1 as date)
                then 1 else 0 end [CurrentDate-2]
        , case when CaseRegisterTime >= cast('20120101' as date)
                and CaseRegisterTime < cast(getdate() - 2 as date)
                then 1 else 0 end [January2012-CurrentDate-3]
    from MyTable 
    where StatusID = 1
        and StageID = 5
) as a
group by a.City
person Tim Lehner    schedule 22.03.2012

Что-то вроде этого будет делать:

begin tran;
go
create table #t1(
    ID int identity,
    City varchar,
    RegisterDate  datetime
);
declare  @firstDate datetime, @secondDate datetime;
 set @firstDate = '2012-1-1';
 set @secondDate = '2012-1-2';
insert into #t1 values
    ('A', @firstDate),
    ('A', @firstDate),
    ('B', @firstDate),
    ('B', @firstDate),
    ('B', @firstDate),
    ('A', @secondDate),
    ('A', @secondDate),
    ('A', @secondDate),
    ('B', @secondDate),
    ('B', @secondDate);

select * from #t1;

select pvt.*
from(
    select ID, City, RegisterDate
    from #t1
) a
pivot(
    count(a.ID)
    for a.RegisterDate in ([2012-1-1], [2012-1-2])
)   as pvt;

drop table #t1;
go
rollback tran;
person Vitaliy Kalinin    schedule 22.03.2012