每天按小时分组并获取所有记录

时间:2016-12-17 06:32:48

标签: sql-server sql-server-2008

我几乎没有要求分析下表中的数据,

SELECT MId,SId,PId,DataHour,
 CAST(t.[SDate] as DATE), MAX(t.Powers) as PeakPower
 FROM [HourData] t  where CONVERT(date,[SDate]) between 
 CONVERT(date,'2016-12-01 09:45:59.240') and CONVERT(date,'2016-12-08 09:45:59.240')
 GROUP BY MId,SId,PId, CAST(t.[SDate] AS DATE),DataHour 
 order by  CAST(t.[SDate] AS DATE),DataHour,PeakPower

以上查询将获得一天中每小时所有MId,SId,PId的总和。 但我几乎没有其他要求,我需要每天一小时内最常用的PI,即数据链http://ideone.com/IW4FUA 我需要每小时使用最多PId的数据,如下所示。

 Power      PId
 5163.316   6
 5135.371   6

PId 6在当天0小时和小时1的最高值。 每个数据小时中所有pid的总和,并获得每天的最大小时数。

此查询将提供每小时数据的详细信息

 SELECT MId,SId,PId,DataHour,
 CAST(t.[SDate] as DATE), MAX(t.Powers) as PeakPower
 FROM [MonataHourData] t  where CONVERT(date,[SDate]) between 
  CONVERT(date,'2016-12-01 09:45:59.240') and CONVERT(date,'2016-12-08   09:45:59.240')
 GROUP BY MId,SId,PId, CAST(t.[SDate] AS DATE),DataHour 
 order by  CAST(t.[SDate] AS DATE),DataHour,PeakPower

CREATE TABLE [dbo].[HourData](
  [ID] [bigint] NOT NULL,
  [SId] [bigint] NOT NULL,
  [PID] [bigint] NOT NULL,
  [Powers] [decimal](18, 4) NOT NULL,
  [DataHour] [int] NOT NULL,
  [StartDate] [datetime] NOT NULL)

1 个答案:

答案 0 :(得分:0)

有很多方法可以做到这一点,其中一些是:

rextester链接,可以对您的数据进行全面测试:http://rextester.com/KBO56228

--declare @from datetime = '2016-12-01 09:45:59.240';
--declare @thru datetime = '2016-12-08 09:45:59.240';
/* the above can be simplified to: */
declare @from date = convert(date,'2016-12-01 09:45:59.240', 121);
declare @thru date = convert(date,'2016-12-08 09:45:59.240', 121);

交叉apply 版本:

select distinct
      x.Mid
    , x.Sid
    , x.Pid
    , t.DataHour
    , Date = convert(date, t.SDate)
    , x.Powers
  from HourData t
    cross apply (
      select top 1
          Mid
        , Sid
        , Pid
        , Powers
        from HourData c
        where convert(date, c.sdate) = convert(date, t.sdate)
          and c.DataHour = t.DataHour
        order by c.Powers desc
       ) as x;

top with ties 版本:

select top 1 with ties
      t.Mid
    , t.Sid
    , t.Pid
    , t.DataHour
    , Date = convert(date, t.SDate)
    , t.Powers
  from HourData t
  where convert(date, sdate) >= @from
    and convert(date, sdate) <  @thru
  order by row_number() over (partition by convert(date, t.SDate),t.DataHour order by t.Powers desc);
使用 common table expression

row_number()

with PowerRN as (
select 
      t.Mid
    , t.Sid
    , t.Pid
    , t.DataHour
    , Date = convert(date, t.SDate)
    , t.Powers
    , rn = row_number() over (partition by convert(date, t.SDate),t.DataHour order by t.Powers desc)
  from HourData t
  where convert(date, sdate) >= @from
    and convert(date, sdate) <  @thru
)
select Mid, Sid, Pid, DataHour, Date, Powers
  from PowerRN
  where rn=1
  order by Date, DataHour;

max() over() 版本:

with PeakPower as (
  select 
        t.Mid
      , t.Sid
      , t.Pid
      , t.DataHour
      , Date = convert(date, t.SDate)
      , t.Powers
      , PeakHourPower = max(t.Powers) over (partition by convert(date, t.SDate),t.DataHour)
    from HourData t
    where convert(date, sdate) >= @from
      and convert(date, sdate) <  @thru
    group by 
        t.Mid
      , t.Sid
      , t.Pid
      , convert(date, t.SDate)
      , t.DataHour
      , t.Powers
)
select Mid, Sid, Pid, DataHour, Date, Powers
  from PeakPower
  where Powers = PeakHourPower
  order by Date, DataHour;

inner join版本:

select 
      t.Mid
    , t.Sid
    , t.Pid
    , t.DataHour
    , Date = convert(date, t.SDate)
    , t.Powers
  from HourData t
    inner join (
      select 
          DataHour
        , Date = convert(date, t.SDate)
        , PeakHourPower = max(t.Powers) 
        from HourData t 
        where convert(date, sdate) >= @from
          and convert(date, sdate) <  @thru
        group by 
            convert(date, SDate)
          , DataHour 
       ) as x on x.Date          = convert(date, sdate)
            and x.DataHour      = t.DataHour 
            and x.PeakHourPower = t.Powers

  where convert(date, sdate) >= @from
    and convert(date, sdate) <  @thru;
  order by t.Date, t.DataHour;