SQL Server给了我不同的结果

时间:2014-08-29 22:08:31

标签: sql sql-server tsql sql-server-2012

;with sub as
(
    select 
        x.*,
        row_number() over(partition by wdl order by id) - row_number() over(order by id) as grp
    from 
        (select 
             id, hometeam as team, wdl 
         from 
             #HomeTeam_vs_AwayTeam
         where 
             hometeam = @Team

         union all

         select 
             id, awayteam,wdl
         from 
             #HomeTeam_vs_AwayTeam
         where 
             awayteam = @Team) x
)
INSERT INTO #Team_Streak([Team], [WDL], [Streak])
   (select 
        team, wdl, count(*) as count
    from 
        sub
    where 
        grp = (select grp from sub where id = (select max(id) from sub))
    group by 
        team, wdl) 

为什么这个查询会给我一个不同的结果,有时会给我两个结果?

我正在使用SQL Server 2012

1 个答案:

答案 0 :(得分:0)

基本问题是计算grp的方式不会将条纹放入唯一的组中。 在#HomeTeam_vs_AwayTeam中获取以下数据,例如:

id | hometeam | awayteam | wdl
---+----------+----------+----
 1 | team A   | team B   | W
 2 | team A   | team B   | L
 3 | team A   | team B   | W

如果你看一下子为此生成的是:

id | team   | wdl | grp
---+--------+-----+----
 1 | team A | W   | 0
 2 | team A | L   | -1
 3 | team A | W   | -1

I.e grp -1包含WL的值。这是因为row_number() over (partition by wdl order by id)不会在条纹之间重置。 Example SQLFiddle

解决问题的一种方法如下,尽管感觉这应该可以简化

with results as (
    select 
        id, hometeam as team, wdl 
    from 
        #HomeTeam_vs_AwayTeam
    where 
        hometeam = @Team
    union all
    select 
        id, awayteam,wdl 
        -- wdl should probably be 
        -- case wdl when 'W' then 'L' when 'D' then 'D' when 'L' then 'W' end
    from 
        #HomeTeam_vs_AwayTeam
    where 
        awayteam = @Team
), sub as (
    select 
        results.*,
        row_number() over(order by id) as rn,
        lag(wdl) over (order by id) as prev_wdl
    from
        results
), limits as (
    select
        max(id) id,
        max(rn) - max(case when wdl != prev_wdl then rn else 1 end) + 1 streak
    from
        sub
) select
    results.team,
    results.wdl,
    limits.streak
from
    limits
        inner join
    results
        on limits.id = results.id

Example SQLFiddle