【问题标题】:SQL cross tab pivot querySQL 交叉表数据透视查询
【发布时间】:2012-04-07 02:02:56
【问题描述】:

我有一张如下表。

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

请帮忙。

【问题讨论】:

  • 尝试谷歌搜索数据透视表查询 sql 你会发现很多你正在尝试做的例子。
  • 我尝试过旋转,但主要问题是我只限制了日期列,如上面的示例输出所示,有限日期不想查找所有其他日期。
  • 你从哪里得到日期?一般来说,当我们问“你试过什么?”我们想看代码
  • @Keyur,请提供更有意义的数据(即使它是假的)......很难看出你想要的结果来自哪里。那些 CurrentDate 列应该是计数、总和还是什么?
  • @Brian Just Google 这没有帮助.. 因为当其他人在进行 Google 搜索时,他们会不断得到结果,上面写着“只需 Google it”。导致讨厌的递归。

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


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    这是在 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
    

    【讨论】:

      【解决方案3】:

      这样就可以了:

      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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多