SQL查询以获取组中的趋势

时间:2015-08-18 17:45:23

标签: sql sql-server tsql

我遇到SQL查询问题

我有一张这样的表

Person     Scoring date      Score
--------------------------------------
Person1    20150818          9.5
Person1    20150817          8.5
Person1    20150816          6.5
Person2    20150818          5.5
Person2    20150817          8.5
Person2    20150816          7.5
Person3    20150818          8.5
Person3    20150817          8.5
Person3    20150816          6.5

我需要以这种格式获得结果

Person     Scoring date      Score  Current_flag  Trend  
--------------------------------------------------------
Person1    20150818          9.5       1            UP
Person1    20150817          8.5       0            null
Person1    20150816          6.5       0            null
Person2    20150818          5.5       1            DOWN
Person2    20150817          8.5       0            null
Person2    20150816          7.5       0            null
Person3    20150818          8.5       1            EQUAL
Person3    20150817          8.5       0            null
Person3    20150816          6.5       0            null
  1. 最新的标志必须位于最新的日期字段。
  2. 趋势字段将当前字段与前一天进行比较
  3. 有人可以帮助我查询我的第一张桌子以获得第二张吗?

    我尝试使用GROUP BY功能,但无法找到解决方案。

    由于

3 个答案:

答案 0 :(得分:2)

如果您使用的是SQL Server 2012+版本 然后你可以尝试以下查询:

用于演示的SQL小提琴:http://sqlfiddle.com/#!6/3ca38/4

select 
    Person, 
    Scoring_Date,
    Score, 
    current_flag, 
    CASE WHEN current_flag=1 then Trend else NULL end as Trend
from
(
    select 
      Person,
      Scoring_date,
      Score,
      case when MAX(scoring_date) over(partition by Person order by Person) =scoring_date
      then 1 else 0 end  
      as current_flag,
      case 
        when 
            LAG(score,1) over (partition by Person order by scoring_date)>score then 'DOWN' 
        when 
            LAG(score,1) over (partition by Person order by scoring_date)< score then 'UP' 
        when 
            LAG(score,1) over (partition by Person order by scoring_date)= score then 'EQUAL' 
        else 
            NULL
        end 
            as Trend
     from tbl
 ) tbl
 order by Person asc, scoring_date desc

对于2008版本,请尝试以下查询,因为LAG/LEAD在2008版本中不可用 这个版本的Sql小提琴:http://sqlfiddle.com/#!3/3ca38/2

select 
        t.Person,
        t.scoring_date,
        t.score,
        t.current_flag,
        case 
            when 
                t2.score>t.score then 'DOWN' 
        when 
                t2.score<t.score then 'UP' 
        when 
                t2.score=t.score then 'EQUAL' 
        else 
            NULL
        end 
            as Trend
    from 
    (
        select 
          Person,
          Scoring_date,
          Score,
          case when MAX(scoring_date) over(partition by Person order by Person) =scoring_date
          then 1 else 0 end  
          as current_flag,
          RANK() over(partition by Person order by Person,Scoring_Date) as r
        from tbl
    ) t 
    left join 
    (
        select 
          Person,
          Scoring_date,
          Score,
          RANK() over(partition by Person order by Person,Scoring_Date) as r
        from tbl
    ) t2   
    on t.Person=t2.Person and 
    t.r-1=t2.r
    and t.current_flag=1
    order by Person asc, scoring_date desc

答案 1 :(得分:0)

不是一切,只是一个正确的开始

with cte as 
(  select Person, Scoring date, Score, 
          row_number() over (partition by Person order by scoring date desc) as rn  
     from table 
)
select cte1.* 
  from cte as cte1  
  left join cte as cte2 
    on cte1.person = cte2.person 
   and cte1.rn = 1 
   and cte2.rn = 2 

答案 2 :(得分:0)

这可以通过窗口函数轻松完成:

create table t(Person varchar(7), Scoring date, Score money)

insert into t values
('Person1', '20150818', 9.5),
('Person1', '20150817', 8.5),
('Person1', '20150816', 6.5),
('Person2', '20150818', 5.5),
('Person2', '20150817', 8.5),
('Person2', '20150816', 7.5),
('Person3', '20150818', 8.5),
('Person3', '20150817', 8.5),
('Person3', '20150816', 6.5);

with cte as(select *, 
                   row_number() 
                     over(partition by Person order by Scoring desc) rn from t)
select c1.Person, 
       c1.Scoring,
       c1.Score, 
       case when c1.Score > c2.Score then 'up'
            when c1.Score < c2.Score then 'down'
            when c1.Score = c2.Score then 'equal'
       end as Trend
from cte c1
left join cte c2 on c1.Person = c2.Person and c1.rn = 1 and c2.rn = 2

小提琴:http://sqlfiddle.com/#!3/f49e4/1