3

我什至不确定这是否可以仅使用 SQL 来实现,但这里......

我在一个表中有一个足球结果列表,每一行都是一场比赛,并包含该比赛的所有数据,即 Home(team)、HomeGoals、AwayGoals、Away(team),我想循环浏览每场比赛,得到主队,查看他们最近的 6 场比赛并仅显示指定球队在最近 6 场比赛中 50% 或更多的进球数为 2 或更多的比赛。

到现在为止,我只是不知道如何将它缝合在一起......

创建所有比赛的列表,只返回主队:

SELECT *
FROM [FDATA].[dbo].[Goals]
ORDER BY Date

获取该球队的最后 6 场比赛:(我想对上述查询的每一行进行以下查询)

SELECT TOP 6 *
FROM [FDATA].[dbo].[Goals]
WHERE Home = '[Home] from first query'  AND Date <= '[Date] from first query'  
ORDER BY Date DESC

然后检查球队在返回的 6 场比赛中是否有 >= 50% 的球进了 2 球或更多球,如果为真,则输出第一个查询中的行。

所以基本上对于数据库中的每一行,我想找到该行(比赛)中主队的最后 6 场比赛,看看他们是否在 50% 或更多的比赛中进了 2 球或更多球,如果是,则输出原始行,如果不是,则从结果中省略该行。

可能吗?

4

3 回答 3

0

如果您使用的是 SQL Server 2005 及更高版本:

WITH RankedGoals AS (
   SELECT
      *,
      Sequence = Row_Number() OVER (PARTITION BY G.Home ORDER BY G.Date DESC)
   FROM FDATA.dbo.Goals G
)
SELECT
   G.*
FROM
   RankedGoals G
WHERE
   EXISTS (
      SELECT
         *
      FROM
         RankedGoals S
      WHERE
         G.Home = S.Home
         AND S.Sequence BETWEEN G.Sequence AND G.Sequence + 5
      HAVING
         Sum(CASE WHEN S.Goals >=2 THEN 1 ELSE 0 END) >= 3
         AND Count(*) = 6
   )
;

可以修改查询,以便该EXISTS部分使用TOP 6日期搜索代替,这可能会执行得更好,因为它不必执行窗口功能。但我不确定该Date列是否保证是唯一的。如果是这样,这很容易:

SELECT
   G.*
FROM
   FDATA.dbo.Goals G
WHERE
   EXISTS (
      SELECT
         *
      FROM
         (
            SELECT TOP 6 *
            FROM
               FDATA.dbo.Goals S
            WHERE
               G.Home = S.Home
               AND S.Date <= G.Date
            ORDER BY
               S.Date
          ) S
      HAVING
         Sum(CASE WHEN S.Goals >=2 THEN 1 ELSE 0 END) >= 3
         AND Count(*) = 6
   )
;

我强烈建议在HomeandDate列上有一个索引...

于 2013-07-22T17:03:30.600 回答
0
SELECT *, NULL as 50percent2ormore
FROM [FDATA].[dbo].[Goals]
INTO #tempgames
ORDER BY Date

Update #tempgames
SET 50percent2ormore = 'Yes'
FROM ( 
SELECT TOP 6 *, count('games with 2 or more goals') as count
FROM #tempgames
WHERE Home = #tempgames.home  
AND Date <= #tempgames.date
ORDER BY Date DESC 
) tmp
WHERE tmp.count >= 3

SELECT * FROM #tempgames WHERE 50percent2ormore = 'Yes'

这可能是一个开始的地方......

于 2013-07-22T17:11:38.243 回答
0

假设 SQL Server 2012。未经测试,但我认为这应该有效:

WITH Last6 as (
  SELECT 
    Home, HomeGoals, 
    ROW_NUMBER() OVER (PARTITION BY Home ORDER BY Goals.Date DESC) GameNumber
  FROM Goals
),
Medians as (
  SELECT 
    Home, 
    PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY HomeGoals) OVER (PARTITION BY Home) GoalMedian
  FROM Last6
  WHERE GameNumber <= 6
)    
SELECT *
FROM Goals G
WHERE EXISTS (SELECT NULL FROM Medians WHERE G.Home = Medians.Home AND GoalMedian >= 2)
于 2013-07-22T17:20:00.627 回答