SQL交叉表透视表查询

时间:2012-03-22 13:42:03

标签: sql sql-server sql-server-2008 tsql crosstab

我有一张桌子如下。

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分组案例,如上所示。

请帮忙。

3 个答案:

答案 0 :(得分:0)

使用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

你还必须过滤掉没有所需日期的寄存器。

答案 1 :(得分:0)

以下是在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

<强>更新

@JotaBe使用的case和sum方法在我的盒子上快了两倍(扫描和读取次数少了很多),所以这就是看起来的样子:

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

答案 2 :(得分:0)

这样的事情会:

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;