I have some database I need to query.
It is necessary to write a query that finds out how many times the teams played among themselves. It is important if Team A plays against Team B and then Team B plays against Team A, it counts as the same event. That is, the result should be: A against B - 2 games.
SELECT
least(home_team, away_team) AS A
,greatest(home_team, away_team) AS B
,COUNT(*) AS games_count
FROM event_entity
GROUP BY A, B
HAVING COUNT(*) >= 1
ORDER BY A, B
I have this query.
But need this solve.
3 first rows in solving
Novara-Udinese 1
Brescia-Genoa 1
Fc Pacos de Ferreira - Trofense 1
This is my schema:
You already have the query that you need to build on the logic of getting the number of count of games. In order to display the event you can do as follows.
SELECT MAX(CONCAT(home_team,'-',away_team)) as game
,COUNT(*) AS games_count
FROM event_entity
GROUP BY least(home_team, away_team), greatest(home_team, away_team)
ORDER BY 1
Related
I have 2 tables:
Battles
--battleId(primary)--gameId(foreign)--endTime
BattleParticipants
--battleParticipantId(primary)--userId(foreign)--someNumerical--score--battleId(foreign)
Given userId, i want to get only ended battle data for each battle user participated in with additional player rank information and total number of player participated in battle information.Ended battle means battles only with endTime smaller than current_time
returned battle data should include:
battleId:
endTime:
gameId:
score:
someNumerical:
rankOfPlayerInBattle:
totalNumberOfPlayersParticipatedInBattle:
for each battle player participated.
With below query i can get battleId,endTime,gameId,score,someNumerical as i want:
SELECT b.battleId,b.endTime,b.gameId,bp.score,bp.someNumerical FROM battles b JOIN battleparticipants bp ON b.battleId=bp.battleId WHERE bp.userId="someuserid" AND b.endTime<CURRENT_TIMESTAMP
Given battleId and userId this query returns me rank of user in that battle:
SET #i=0;
SELECT battleId, userId,score, #i:=#i+1 AS myRank
FROM battleparticipants WHERE battleId="asd1234" AND userId="someuserid"
ORDER BY score DESC
Given battleId this query gives me total number of players participated in that battle:
SELECT COUNT(*) FROM battleparticipants WHERE battleId="asd1234"
So given those seperated queries how do i retrieve data i want in one query ? (i dont really need to use above queries i just gave them as example since they get datas i want seperately)
i cant add fiddle because for some reason create code is throwing error. for now i add pictures of tables and data:
Battles table:
BattleParticipants table:
Below query wrong result:
SELECT b.battleId,b.endTime,b.gameId,bp.score,bp.someNumerical , RANK()OVER(PARITITON BY b.battleId, bp.userId order by score desc) rankOfPlayerInBattle , BP_C.CNT totalNumberOfPlayersParticipatedInBattle
FROM battles b
JOIN battleparticipants bp ON b.battleId=bp.battleId
JOIN (SELECT battleId , COUNT(*) CNT FROM battleparticipants GROUP BY battleId) BP_C ON BP_C.battleId=bp.battleId
WHERE bp.userId="someuserid" AND b.endTime<CURRENT_TIMESTAMP
You can use above SQL.
Working on an exercise for school trying to calculate the number of points scored by a basketball player ONLY during their first game.
So if I have a table that reports lots of games (Separate rows for 1st and 2nd half) that looks like this:
Game Date Player Half Points
1990-01-01 Mike 1 10
1990-01-01 Mike 2 10
1990-01-03 Mike 1 5
1990-01-03 Ben 2 8
1990-01-05 Kelly 1 4
1990-01-05 Kelly 2 4
1990-01-07 Kelly 1 10
And I want it to end up like this:
Game Date Player Points
1990-01-01 Mike 20
1990-01-03 Ben 8
1990-01-05 Kelly 8
How would I do this?
I have been trying to use the code:
SELECT min(game_Date), player, sum(points);
But it keeps counting points for ALL games, not just points scored during the 1st game, of which there can be one record for the first half and one record for the second.
First you need to find the players' first games, like this
select player, min(game_date) as firstGameDate
from yourtable
group by player
and then get the points in that game by joining to the table again
select yourtable.player, firstgame.firstGameDate, sum(points) as firstGamePoints
from yourtable
inner join
(
select player, min(game_date) as firstGameDate
from yourtable
group by player
) firstgame
on yourtable.player = firstgame.player
and yourtable.game_date = firstgame.firstgameDate
group by yourtable.player, firstgame.firstgameDate
Some varieties of SQL allow you to use ranking functions which could eliminate the need to join to the table itself, but this will work in all varieties.
You have to use your logic. First you have to only grab the first game for each player (inner query). Then from there, you count the points
SELECT t.game_date, t.player, SUM(t.points)
FROM some_table t
JOIN (
SELECT player, MIN(game_date) AS min_date
FROM some_table
GROUP BY player
) a ON a.plyer = t.player AND a.min_date = t.game_date
GROUP BY t.player, t.game_date
Sub query approach of getting the result is given below
Filter the results only getting Player's first games.
Select min(Game_Date),Player from
basketball group by Player;
Use the results from first query to find each player's sum of scores in first game.
Select Game_Date, Player,sum(points) as first_play_points from
basketball where (Game_date,Player) in (Select min(Game_Date),Player
from basketball group by Player) group by Game_Date, Player;
Working fiddle can be found here
I am trying to select the rows that have the last gameDate, todays gameDate (if exists), and the next gameDate from a table called games for any given team(s). It's structure is as follows:
awayTeam homeTeam gameDate
1 2 5/12/16
2 3 5/13/16
3 5 5/14/16
2 4 5/14/16
The problem I am facing is that the teamID can appear in two columns - awayTeam or homeTeam. I saw a lot of solutions that have the group by clause but that only appears to work for just one column. I would like to get the row which corresponds to the last gameDate for each team. For instance, (1,5) would return:
awayTeam homeTeam gameDate
1 2 5/12/15
3 5 5/14/16
Since I want the most recent games, any games from today, and the next game, I was thinking the best way to solve this would be to first get the past rows, then UNION ALL with the rows from todays date, then UNION ALL with the next game. This table is small with only about 3,000 rows. I have the below query, but it only works for homeTeam and not if it appears in awayTeam. Also, the below query takes 2.2 seconds, which seems rediculously high for a table with such a small number of rows.
SELECT g . *
FROM games g
WHERE g.gameDate = (
SELECT MAX( g2.gameDate )
FROM games g2
WHERE g2.homeTeam = g.homeTeam
AND gameDate < NOW( )
AND g.homeTeam
IN (1, 5) )
ORDER BY g.gameDate DESC
I thought about perhaps splitting this into a view so I could easily get the last time a team has played, regardless of whether they appear in the homeTeam or awayTeam column, but that seems like overkill. This is for MySQL. Thanks for your time.
This isn't pretty but it may help you. The inner most derived table gets all the teams in one column along side their dates. The next part gets each teams last game played date. Join that back to the original table and now you have the most recent last game for each team back in the original format. It's confusing to explain but really quite simple if you run each of the selects one by one working from inner to outer.
SQL Fiddle Demo
SELECT yt.*
FROM
(SELECT
Team
, MAX(GameDate) AS GameDate
FROM
(SELECT AwayTeam AS Team, GameDate
FROM YourTable
UNION ALL
SELECT HomeTeam AS Team, GameDate
FROM YourTable) a
WHERE GameDate < NOW()
GROUP BY
Team) MaxDates
JOIN YourTable yt ON (MaxDates.Team = yt.AwayTeam OR MaxDates.Team = yt.HomeTeam)
AND yt.GameDate = MaxDates.GameDate
WHERE MaxDates.team in (1,5)
I keep track of all european football leagues. But now I want a table with all of the teams and next to it there total goals scored and totals goals against of their last 5 games.
My results table has the following columns:Match_id | Date | home team| Away team | Home Goals | Away goals
So what would the code be for this issue as you have to check both the home team column and away team column to find their last 5 match results??
Pls HELP :D
Getting all goals for a team when it's a home/away team in the last 5 games would be:
SELECT home_team as team, sum(home_goals) as goals FROM tbl a WHERE match_id IN (SELECT match_id FROM tbl b WHERE b.home_team = a.home_team ORDER BY date desc limit 5) GROUP BY home_team
Similarly you can get the away team (lets call this query Q_home and the equivalent for the away team Q_away).
So overall you'd want to do something like:
SELECT team, a.goals+b.goals FROM <Q_home> a JOIN <Q_away> b ON a.team=b.team
Not really sure if this would work but this is the general idea.
The database table contains goal actions.
type goal assist
goal Johnny James
goal Johnny James
goal James Bob
When using GROUP BY goal, assist it displays
player goals assists
Johnny 2 0
Johnny 0 0
James 1 0
James 0 2
Bob 0 0
Bob 0 1
but I need it to show players' goals and assists in one line. Cheers.
You can do it like this (although that might not be the fastest query, depending on the size of your database and indexes!):
SELECT players.player,
-- Use correlated subselects to count goals / assists
(SELECT COUNT(*) FROM actions WHERE goal = players.player) goals
(SELECT COUNT(*) FROM actions WHERE assist = players.player) assists
-- Get all distinct players (UNION = DISTINCT, here). Of course, if you
-- have an actual players table, use that one instead!
FROM (
SELECT goal player FROM actions UNION
SELECT assist FROM actions
) players
From your question, I'm not sure if type = goal is relevant for your query...
A possible solution would be to unpivot the player names first, then group with pivoting:
SELECT
Player,
COUNT(NULLIF(ScoreType, 'assist')) AS goals,
COUNT(NULLIF(ScoreType, 'goal')) AS assists
FROM (
SELECT
CASE s.ScoreType WHEN 'goal' THEN goal ELSE assist END AS Player,
s.ScoreType
FROM GoalActions
CROSS JOIN (
SELECT 'goal' AS ScoreType
UNION ALL SELECT 'assist'
) st
) s
GROUP BY
Player
Unpivoting is done using a cross join to a virtual table, and grouping/pivoting is implemented in the form of aggregating with CASE.