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 | 

マネージャ

私はカムバックの数は管理職のために一致して取得したいです。例えば、コンテのチームは第1戦と第2戦で第1ゴールを許したが、勝利した。だからコンテには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つの一般的なサブクエリ、すなわちMatchIDTeamIDを含む、1)winnersを使用します。そして2)first_goalsには、TeamIDのものが含まれています。これは試合の最初のゴールです。

ので、使用して、これらのサブクエリとの接合:

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

することは私たちのチームが勝ったものmatchsを与えるが、最初の目標(すなわち "カムバック")を獲得しません。

最後に、我々は簡単な使用は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 

これらの2つのクエリを組み合わせることで、カムバックしたチームのチームIDを取得することができます。

私はこの作業がカーソルやテンポラリテーブルの方がはるかに優れていると思っていますが、できるだけ簡単に答えを出したいと思っていました。それゆえ、私はそれを避けました。あなたは間違いなくこれらの2つの方法を探るべきです。

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 

上記のクエリは、私たちに総合的なカムバックを与えます。

1

サッカーの試合ですべてのカムバックをカウントしたい場合は、以下の解決策を使用できます。その後、カムバックの定義は、チームが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) 

、および以前のスコアはさえた:たとえば、次のシナリオのために、私たちは3つのカムバックを持っています。私は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 

注、私はこれを実証するために、1本の以上のマッチを追加しました。

関連する問題