Sum values across multiple tables - mysql

I'm having trouble trying to sum a field GROUPED BY a common user ID from TWO DIFFERENT tables.
To give you a little more info... I am trying to track player performances by date (i.e.: most points scored on ALL Nov. 14's). The database is split, one table for regular season games and one table for playoffs. So, for example, a player may have played a regular season game on May 3, 2001....but a playoff game on May 3, 2005.
So, I'm trying to build a view with the sums of every player on all dates.
What I have for a single table:
SELECT PlayerId,sum(Points) as TOT_PTS
FROM RS_games
WHERE DAY(Date)=$cur_day
AND MONTH(Date)=$cur_month
GROUP BY PlayerId
...but I can't figure how I could sum the values of each player across two tables without creating a third view as a "stepping stone".
Any ideas?

If you want the results by (DAY-MONTH) you can do:
SELECT playerID,
CONCAT (DAY(DATE), '-', MONTH(DATE)) AS DAY_MONTH,
SUM(points) AS Total_Points
FROM (
SELECT playerID, DATE, points
FROM rs_games
UNION ALL
SELECT playerID, DATE, points
FROM po_games
) a
GROUP BY 1, 2
sqlfiddle demo
This way, you would end up with a result with every playerId,dd-mm, and the sum of points that were scored in that specific day across the years.

Just to lay out what I was saying:
select
ALL_players.PlayerID as PlayerID
COALESCE(reg.Points, 0) + COALESCE(po.Points, 0) as Points
from
ALL_players
left join
(select PlayerID, DATE(Date) as Date, sum(Points) as Points
from RS_games
WHERE DAY(Date)=$cur_day AND MONTH(Date)=$cur_month
group by PlayerID) as reg
on reg.PlayerID = ALL_players.PlayerID
left join
(select PlayerID, DATE(Date) as Date, sum(Points) as Points
from PO_games group by DATE(Date), PlayerID
WHERE DAY(Date)=$cur_day AND MONTH(Date)=$cur_month
group by PlayerID) as po
on po.PlayerID = ALL_players.PlayerID
EDIT: Looking again at requirements this will need either a full outer join or some adjustment... adjusting (should be working now)

Related

Selecting a record because its date field is X days after another records date field SQL

I have a table, GameData, with columns; GameID, Date, StartTime, Duration, AteamId, HteamID, Ascore, Hscore, Attendance in my nba db. It basically holds data on NBA games. I want to select all the records for a specific team that are played after X days of rest.
I am having trouble selecting the records so far I have
select * from GameData where Date+2 in (Select Date from GameData) and ATeamID = 1030; But this just gets all the records with Date values that are two days apart for a specific team, but it doesn't check if there a records in between. It should only be selecting games that are 2 days after the last played, not games that are simply 2 days after a game regardless if there are games played in between.
You can unpivot the table with union all to generate one row per game and team, then use lag() to get the date of the "previous" game, and finally use that information to filter:
select gd.*
from (
select gd.*, lag(date) over(partition by team order by date) lag_date
from (
select gd.*, ateam team from gamedata gd
union all
select gd.*, hteam team from gamedata gd
) gd
) gd
where date > lag_date + interval 2 day

How do i combine 3 queries into 1

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.

Cross Play Query

I am trying to find the following variations. I have 10 games and individual ids associated to each game. I need to figure out the following:
distinct count of all who played all 10 games
same but for 9 games
etc
The closest formula I came up with:
SELECT distinct player_id
FROM ticket
WHERE game_code IN ('17','16') AND
create_date BETWEEN '2018-05-01'
AND '2018-05-31'
GROUP BY player_id
HAVING COUNT(*) = 2;

MYSQL For/While Loop

Is it possible to do a For or While loop in MYSQL?
I've got the following code extract, but the full code goes up to home_id_15, home_score_15, away_id_15 and away_score_15:
$query3 = '
SELECT match_date, fixture_id, COUNT(a.home) AS home, SUM(a.points) AS points FROM
(
SELECT match_date, fixture_id, home_id_1 AS home, home_score_1 AS points FROM scores
WHERE home_id_1 =' .intval($_REQUEST['ID']).'
UNION ALL
SELECT match_date, fixture_id, away_id_1 AS home, away_score_1 AS points
FROM scores
WHERE away_id_1 =' .intval($_REQUEST['ID']).'
UNION ALL
SELECT match_date, fixture_id, home_id_2 AS home, home_score_2 AS points
FROM scores
WHERE home_id_2 =' .intval($_REQUEST['ID']).'
UNION ALL
SELECT match_date, fixture_id, away_id_2 AS home, away_score_2 AS points
FROM scores
WHERE away_id_2 =' .intval($_REQUEST['ID']).'
UNION ALL) a
GROUP BY match_date'
The first and second sub-SELECTS are basically being repeated until they reach 15.
This seems a bit long-winded and I was wondering if it's possible to use a loop in MYSQL to output
home_id_1, home_score_1, away_id_1, away_score_1 [up to] home_id_15, home_score_15, away_id_15, away_score_15
, respectively?
Thanks,
Dan.
It looks like you might need to normalize your database a little bit more. Let's say you had 6 scores for each row. Instead of making each score a column, make a separate table called "scores" or something like that with a foreign key column and a score column. Then join the table with this scores table.
Example:
TABLE: team
team_id
name
TABLE: scores
team_id
score
SELECT t.*, s.score
FROM team t
join scores s
on t.team_id=s.team_id;
Todo: Add the concept of matches into your schema and the Join

MySql SUM and JOIN

I am trying to count sales made by a list of sales agents, this count is made every few minutes and updates a screen showing a 'sales leader board' which is updates using a Ajax call in the background.
I have one table which is created and populated every night containing the agent_id and the total sales for the week and month. I create a second, temporary table, on the fly which counts the sales for the day.
I need to combine the two tables to create a current list of sales for all agents in agent_count.
Table agent_count;
agent_id (varchar),
team_id (varchar),
name (varchar),
day(int),
week(int),
month(int)
Table sales;
agent_id (varchar),
day(int)
I can't figure out how to combine these tables. I think I need to use a join as all agents must be returned - even if they don't appear in the agent_count table.
First I make a simple call to get the week and month totals for all agents
SELECT agent_id, team_id, name, week, month FROM agent_count;
the I create a temporary table of todays sales, and then I count the sales for each agent for the day
CREATE TEMPORARY TABLE temp_todays_sales
SELECT s.id, s.agent_id
FROM sales s
WHERE DATEDIFF(s.uploaded, NOW()) = 0
AND s.valid = 1;
SELECT tts.agent_id, COUNT(tts.id) as today
FROM temp_todays_sales tts
GROUP BY tts.agent_id;
What is the best/easiet way to combine these to end up with a resultset such as
agent_id, team_id, name, day, week, month
where week and month also include the daily totals
thanks for any help!
Christy
SELECT s.agent_id, ac.team_id, ac.name,
s.`day` + COALESCE(ac.`day`, 0) AS `day`,
s.`day` + COALESCE(ac.`week`, 0) AS `week`,
s.`day` + COALESCE(ac.`month`, 0) AS `month`
FROM sales s
LEFT JOIN
agent_count ac
ON ac.agent_id = s.agent_id
team_id and name will be NULL if there is no record in agent_count for an agent.
If the agents can be missing from both tables, you normally would need to make a FULL JOIN but since MySQL does not support the latter you may use its poor man's substitution:
SELECT agent_id, MAX(team_id), MAX(name),
SUM(day), SUM(week), SUM(month)
FROM (
SELECT agent_id, NULL AS team_id, NULL AS name, day, day AS week, day AS month
FROM sales
UNION ALL
SELECT *
FROM agent_count
) q
GROUP BY
agent_id