How to count incrementally in SQL Server

后端 未结 2 1280
悲哀的现实
悲哀的现实 2021-01-15 04:33

I am assigned a problem which I am not sure how to solve in SQL Server (version 5/8). Here is the simple query and its output:

Select location, date_time, It         


        
相关标签:
2条回答
  • 2021-01-15 04:51

    The above, from cyberkiwi, is too complicated. You need to do something called a 'table rotation'. Assuming you have a product table like this:

    create table product
    (
      location  char(2)     not null ,
      date_time datetime    not null ,
      item_sold varchar(32) not null ,
    
      primary key clustered ( location , date_time ) ,
    )
    

    The sql you want is the following SELECT statement:

    select Location       = loc.location  ,
           "12/8"         =  t8.sales_cnt ,
           "12/8 - 12/09" =  t9.sales_cnt ,
           "12/8 - 12/10" = t10.sales_cnt ,
           "12/8 - 12/11" = t11.sales_cnt ,
           "12/8 - 12/12" = t12.sales_cnt ,
           "12/8 - 12/13" = t13.sales_cnt
    from      ( select distinct location from #product ) loc
    left join ( select location , sales_cnt = count(*) from #product where date_time between '2011-12-08 00:00:00.000' and '2011-12-08 23:59:59.997' group by location ) t8  on t8.location  = loc.location
    left join ( select location , sales_cnt = count(*) from #product where date_time between '2011-12-08 00:00:00.000' and '2011-12-09 23:59:59.997' group by location ) t9  on t9.location  = loc.location
    left join ( select location , sales_cnt = count(*) from #product where date_time between '2011-12-08 00:00:00.000' and '2011-12-10 23:59:59.997' group by location ) t10 on t10.location = loc.location
    left join ( select location , sales_cnt = count(*) from #product where date_time between '2011-12-08 00:00:00.000' and '2011-12-11 23:59:59.997' group by location ) t11 on t11.location = loc.location
    left join ( select location , sales_cnt = count(*) from #product where date_time between '2011-12-08 00:00:00.000' and '2011-12-12 23:59:59.997' group by location ) t12 on t12.location = loc.location
    left join ( select location , sales_cnt = count(*) from #product where date_time between '2011-12-08 00:00:00.000' and '2011-12-13 23:59:59.997' group by location ) t13 on t13.location = loc.location
    order by 1
    
    0 讨论(0)
  • 2021-01-15 05:07

    Sample table and data

    create table Product(Location char(2), Date_time datetime, Item_sold varchar(20))
    insert Product select 'VA', '20101210 1:30:00 PM' ,'Candy'
    insert Product select 'VA', '20101210 3:30:00 PM' ,'Chips'
    insert Product select 'VA', '20101213 12:50:00 AM' ,'Wine'
    insert Product select 'DC', '20101213 8:00:00 AM' ,'Gum'
    insert Product select 'DC', '20101213 12:30:00 PM' ,'Bags'
    insert Product select 'DC', '20101213 1:16:00 PM' ,'Cheese'
    insert Product select 'DC', '20101213 12:00:00 AM' ,'Hotdog'
    insert Product select 'NJ', '20101215 12:00:00 AM' ,'Coffee'
    insert Product select 'NJ', '20101215 1:15:00 PM' ,'Beers'
    insert Product select 'NJ', '20101215 3:45:00 AM' ,'Cream'
    

    The T-SQL to produce the results required

    declare @start datetime
    declare @end datetime
    select @start = '20101208', @end = '20110105'
    
    declare @sql nvarchar(max);
    -- generate the column names
    select @sql = coalesce(@sql + ',', '') + QuoteName(Convert(char(5),@start,101)+' - '+Convert(char(5),DT,101))
    from (
        select @start + number DT
        from master..spt_values
        where type='P' and number between 0 and DATEDIFF(D,@start,@end)) T;
    
    -- replace the column names into the generic PIVOT form
    set @sql = REPLACE('
    ;with COUNTS AS (
        select p.location, Convert(char(5),@start,101)+'' - ''+Convert(char(5),@start + v.number,101) DT, X.C
        from 
        (
            Select distinct location From Product
            where Date_time >= @start and Date_time < @end+1 -- * the date after, to handle the times
        ) p
        inner join master..spt_values v on v.type=''P'' and v.number between 0 and DATEDIFF(D,@start,@end)
        cross apply
        (
            select COUNT(*) C from product p2
            where p2.Location=p.Location
            and p2.date_time >= @start and p2.date_time < @start + v.number +1
        ) X
    )
    select location, :columns:
    from COUNTS p
    pivot (max(C) for DT in (:columns:)) pv',
    ':columns:', @sql)
    
    -- execute for the results
    exec sp_executesql @sql, N'@start datetime,@end datetime', @start, @end
    
    0 讨论(0)
提交回复
热议问题