2017-05-20 108 views
1

我有4張桌子。用SQL查詢在足球數據庫中查找回復

匹配

| id | HomeTeamID | AwayTeamID | 
--------|-------------|------------ 
| 1  | 1   | 2 
| 2  | 1   | 3 
| 3  | 3   | 1 

目標

| id | MatchID  | Minute | TeamID 
--------|-------------|---------- |--------- 
| 1  | 1   |  3  | 2 
| 2  | 1   |  5  | 1 
| 3  | 1   |  15 | 1 
| 4  | 2   |  43 | 3 
| 5  | 2   |  75 | 1 
| 6  | 2   |  85 | 1 
| 7  | 3   |  11 | 1 
| 8  | 3   |  13 | 3 
| 9  | 3   |  77 | 3 

| id | Name  | 
--------|-------------| 
| 1  | Chelsea  | 
| 2  | Arsenal  | 
| 3  | Tottenham | 

名經理

我想復出的數量爲管理者相匹配。例如,孔蒂的球隊在第一場比賽和第二場比賽中承認了第一個進球,但他們贏了。所以康特有2個復出。 Pochettino在比賽3時有1次復出。我想用SQL Query來找到它。

我發現了每支球隊的首場比賽進球。但是經過一些步驟,我正在失去我正在做的事情。

SELECT MatchID, MIN(minute), g.TeamID 
FROM Goals g 
JOIN Managers m ON m.TeamID = g.TeamID 
GROUP BY MatchID, g.TeamID 

回答

0

這裏「復出」意味着球隊承認第一個進球,但球隊贏得了這場比賽。

我使用2個一般子查詢,1)winners其中包含MatchIDTeamID從每個遊戲,不結束爲繪製。和2)first_goals,其中包含那些TeamID的,在比賽中取得第一個進球。

因此,使用這些子查詢之間的連接:

on winners.MatchID = first_goals.MatchID and winners.TeamID <> first_goals.TeamID

給我們的配襯,其中隊贏了,但沒有進球的第一個目標(即「復出」)。

最後我們使用TeamsManagers表簡單連接:

with Goals(id , MatchID , Minute ,TeamID) as (
    select 1  , 1   ,  3  , 2 union all 
    select 2  , 1   ,  5  , 1 union all 
    select 3  , 1   ,  15 , 1 union all 
    select 4  , 2   ,  43 , 3 union all 
    select 5  , 2   , 75 , 1 union all 
    select 6  , 2   ,  85 , 1 union all 
    select 7  , 3   ,  11 , 1 union all 
    select 8  , 3   ,  13 , 3 union all 
    select 9  , 3   ,  77 , 3 
), 
Teams (id, Name) as(
    select 1  ,'Chelsea' union all 
    select 2  ,'Arsenal' union all 
    select 3  ,'Tottenham' 
), 
Managers(id, Name, TeamID) as (
select 1 ,'Conte', 1 union all 
select 2  ,'Wenger', 2 union all 
select 3  ,'Pochettino', 3 
) 

select winners.TeamID, winners.MatchID, Teams.Name, Managers.Name from ( 
    select t1.* from 
    (
     select TeamID, MatchID, count(*) as goal_scored from Goals 
     group by TeamID, MatchID 
    )t1 
    inner join 
    (
     select MatchID, max(goal_scored) as winner_goals_cnt from (
      select TeamID, MatchID, count(*) as goal_scored from Goals 
      group by TeamID, MatchID 
     )t 
     group by MatchID 
     having min(goal_scored) <> max(goal_scored) 
    )t2 
    on t1.MatchID = t2.MatchID and t1.goal_scored = t2.winner_goals_cnt 
) winners 
inner join 
(
    select * from (
    select Goals.*, row_number() over(partition by MatchID order by Minute, id) rn from Goals 
    ) f 
    where rn = 1 
) first_goals 
on winners.MatchID = first_goals.MatchID and winners.TeamID <> first_goals.TeamID 
inner join Teams 
on winners.TeamID = Teams.id 
inner join Managers 
on winners.TeamID = Managers.TeamID 
0

我不遵循足球很多的,但假設捲土重來是當一支球隊承認的第一個進球,但隨後贏得了比賽,我會用下面的邏輯來得到結果。

首先,我們需要一個曾在比賽中失球第一個進球的球隊:

SELECT TeamID, MatchID FROM Goals WHERE GoalID in 
    (SELECT Min(GoalID) FROM Goals GROUP BY MatchID) 

其次,對於每場比賽,我們需要在那裏做的第一個進球的球隊去贏得比賽。

SELECT MatchID FROM 
(SELECT COUNT(GoalID) as TotalGoals, MatchID FROM Goals GROUP BY MatchID) AS MatchSummary 
INNER JOIN 
(SELECT COUNT(GoalID) as TeamGoals, MatchID FROM 
    (SELECT TeamID, MatchID FROM Goals WHERE GoalID in 
     (SELECT Min(GoalID) FROM Goals GROUP BY MatchID) 
) as GoalsOfTheTeamThatConcededFirstGoal 
GROUP BY MatchID) as SummaryOfTeamThatConcededFirstGoal 
ON MatchSummary.MatchID = SummaryOfTeamThatConcededFirstGoal.MatchID 
WHERE (TotalGoals - TeamGoals) < TeamGoals 

結合這兩個查詢,您將能夠獲得已經卷土重來的團隊的TeamID。

我認爲使用遊標或臨時表可以完成這項任務,但我希望儘可能簡單。因此我避免了它。你一定要探索這兩種方法。

1
with cte 
(
MatchID,TeamID,TotalGoalTime,NoOfGoals,ManagerName,comeback) 
as(SELECT MatchID, g.TeamID,sum(minutea) as'TotalGoalTime' ,count(*)as'NoOfGoals',m.name as'ManagerName' 
,comeback =ROW_NUMBER() OVER(PARTITION BY MatchID order by sum(minutea) desc) 
FROM Goals g 
JOIN Managers m ON m.TeamID = g.TeamID 
join [Teams] t on t.Id=g.TeamId 
GROUP BY MatchID, g.TeamID,m.name) 
Select MatchID,TeamID,NoOfGoals,ManagerName from cte where comeback =1 

上述查詢現在給我們整體復出,將更新回來no。

1

如果你想統計足球比賽中的每一次復出,你可以使用下面的解決方案。然後,復出的定義是每當一個球隊在丟失後比對手多一個球。例如,對於下面的情況下,我們有三個回擊:

Team A Team B 
    0 - 1  //team b scores 
    1 - 1  //team a scores 
    2 - 1  //team a scores (comeback for a) 
    2 - 2  //team b scores 
    2 - 3  //team b scores (comeback for b) 
    3 - 3  //team a scores 
    4 - 3  //team a scores (comeback for a) 

從上面我們似乎有捲土重來,當比分被改變,和以前的比分是偶數。我使用SUMOVERROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW排序爲minute,以便在每次進球時計算得分。

這裏充滿工作示例:

DECLARE @matches TABLE 
( 
    [id] TINYINT 
    ,[HomeTeamID] TINYINT 
    ,[AwayTeamID] TINYINT 
); 

DECLARE @Goals TABLE 
(
    [id] TINYINT 
    ,[MatchID] TINYINT 
    ,[Minute] TINYINT 
    ,[TeamID] TINYINT 
); 

DECLARE @Teams TABLE 
(
    [id] TINYINT 
    ,[Name] VARCHAR(12) 
); 

DECLARE @Managers TABLE 
(
    [Id] TINYINT 
    ,[Name] VARCHAR(12) 
    ,[TeamID] TINYINT 
); 

INSERT INTO @matches ([id], [HomeTeamID], [AwayTeamID]) 
VALUES (1, 1, 2) 
     ,(2, 1, 3) 
     ,(3, 3, 1) 
     ,(4, 1, 4); 

INSERT INTO @Goals ([id], [MatchID], [Minute], [TeamID]) 
VALUES (1, 1, 3, 2) 
     ,(2, 1, 5, 1) 
     ,(3, 1, 15, 1) 
     ,(4, 2, 43, 3) 
     ,(5, 2, 75, 1) 
     ,(6, 2, 85, 1) 
     ,(7, 3, 11, 1) 
     ,(8, 3, 13, 3) 
     ,(9, 3, 77, 3) 
     ,(10, 4, 3, 1) 
     ,(11, 4, 5, 4) 
     ,(12, 4, 10, 4) 
     ,(13, 4, 12, 1) 
     ,(14, 4, 25, 1) 
     ,(15, 4, 46, 4) 
     ,(16, 4, 60, 4) 
     ,(17, 4, 72, 4) 
     ,(18, 4, 84, 4); 

INSERT INTO @Teams ([id], [Name]) 
VALUES (1, 'Chelsea') 
     ,(2, 'Arsenal') 
     ,(3, 'Tottenham') 
     ,(4, 'Real Madrid'); 

INSERT INTO @Managers ([Id], [Name], [TeamID]) 
VALUES (1, 'Conte', 1) 
     ,(2, 'Wenger', 2) 
     ,(3, 'Pochettino', 3) 
     ,(4, 'Zidane', 4); 

WITH DataSource AS 
(
    SELECT m.[id] 
      ,m.[HomeTeamID] 
      ,m.[AwayTeamID] 
      ,ROW_NUMBER() OVER (PARTITION BY m.[id] ORDER BY g.[minute]) AS [EventID] 
      ,IIF 
      (
       SUM(IIF(m.[HomeTeamID] = g.[teamID], 1, 0)) OVER (PARTITION BY m.[id] ORDER BY g.[minute] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) - 1 
       = 
       SUM(IIF(m.[AwayTeamID] = g.[teamID], 1, 0)) OVER (PARTITION BY m.[id] ORDER BY g.[minute] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 
       OR 
       SUM(IIF(m.[HomeTeamID] = g.[teamID], 1, 0)) OVER (PARTITION BY m.[id] ORDER BY g.[minute] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 
       = 
       SUM(IIF(m.[AwayTeamID] = g.[teamID], 1, 0)) OVER (PARTITION BY m.[id] ORDER BY g.[minute] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) -1 
       ,IIF(m.[HomeTeamID] = g.[teamID], 'H', 'A') -- (H)ome come back, (A)way come ba 
       ,'N' -- no come back 
      ) AS [ComeBack] 
    FROM @matches m 
    INNER JOIN @Goals g 
     ON m.[id] = g.[MatchID] 
) 
SELECT T.[Name] 
FROM DataSource DS 
INNER JOIN @Teams T 
    ON IIF([ComeBack] = 'H', [HomeTeamID], [AwayTeamID]) = T.[id] 
WHERE DS.[EventID] <> 1 
    AND DS.[ComeBack] <> 'N'; 

上面會給我們:

Chelsea 
Chelsea 
Chelsea 
Tottenham 
Real Madrid 
Real Madrid 

注意,我還增加了一個比賽證明這一點。