Optimize SQL to find sports (basketball) lineups - mysql

I am trying to setup a SQL database to record the 3 person lineups that have occurred in the game. The structure I have now is:
Player
playerID
playerName
Lineup
lineupID
Lineup_players
lineupID (foreign key)
playerID (foreign key)
I want to find a quick way to check whether a particular set of 3 players are already part of a lineup. Suppose I want to find a lineup with players A,B,C, the solution I can think of is something like:
SELECT t1.lineupID
FROM (SELECT lineupID FROM Lineup_players WHERE playerID=A) t1
INNER JOIN (SELECT lineupID FROM Lineup_players WHERE playerID=B) t2 ON t1.lineupID = t2.lineupID
INNER JOIN (SELECT lineupID FROM Lineup_players WHERE playerID=C) t3 ON t1.lineupID = t3.lineupID
I feel that this is a clumsy solution. Is there a faster query using the same tables, or is there a better way to store the data?
Also, if I have players A,B,C,D,E in my lineup, is there a fast way of finding all lineups with any 3 of these players without checking all 20 combinations?

Maybe you're looking something like this?
select
lineupid,
count(*)
from
Lineup_players
where
playerid in (A,B,C,D,E)
group by
lineupid
having
count(*) >= 3
This will list you the lineups that have 3 or more of the listed ids.

Related

Joining three junction tables

my heads hurt from trying to figure this out!
I have three tables
-Players
-Teams
-Games
Three junction tables with two columns.
-player_teams
-teams_games
-player_games
I need to list all Players who are in a Game (eg: Game_id = 111 from variable) that are not assigned a Team(in this game). i call them orphaned players
Basically get Teams that are in the game, get their Players and reverse match against Games_players. or the other way round i suppose.
i tried for two day no luck!
thanks!
/J
p.s after i posted this i got this far but it seems to complex!
SELECT * from players
JOIN
(SELECT DISTINCT games_players.player_id from games_players
Left JOIN
(Select team_players.player_id p1 from team_players
inner join (Select * from games_teams where games_teams.game_id = :P1) AS tm1 ON team_players.team_id = tm1.team_id) As f1
On games_players.player_id = f1.p1
where p1 is null) as q1
on players.player_id = q1.player_id
As the game is given, you can just look at the players in the game and the players of the teams in the game:
select *
from players
where player_id in
(
select player_id
from player_games
where game_id = 111
)
and player_id not in
(
select pt.player_id
from player_teams pt
join teams_games tg using (team_id)
where tg.game_id = 111
);

Get HomeTeam ID and AwayTeam ID of each game for a specific date

I have 2 tables:
Table 1 called teams: that contains different columns like Team_ID, Team_Name... etc.
table 2 called matches: that contains different columns like Match_ID, Home, Away, Match_Date.
Home and away are the names of 2 teams that I generated,
I tried different queries to generate a result where I have teams ID instead of teams names
for example:
SELECT t1.Home,t2.Away from
(SELECT a.Team_ID AS Home, b.Match_Date from teams a
INNER JOIN matches b ON a.Team_Name=b.Home
Where b.Match_Date="2020-05-29 23:59:59") t1,
(SELECT a.Team_ID AS Away, b.Match_Date from teams a
INNER JOIN matches b on a.Team_Name=b.Away
Where b.Match_Date="2020-05-29 23:59:59") t2;
But it didn't give me the result that I'm looking for
and After getting the result, I just to want filter it using a specific date like WHERE Match_Date= "date"
An image to clarify what I'm trying to do:
You want two joins on teams (one for the home team and the other for the away team), and a where clause to filter on the match date:
select th.team_id home, ta.team_id away, m.match_date
from matches m
inner join teams th on th.team_name = m.home
inner join teams ta on ta.team_name = m.away
where m.match_date = 'date1'
Note that you should not be storing the team name in matches, but the team id instead (which, presumably, is the primary key of teams).

Selecting an entity based off a compare condition in another table

I have two tables. These are not them but it is the same principle:
Table:One (artists)
--------------
id (Primary Key)
name
best genre
Table:Two (artist teams)
-------------
id1 (Foreign Key)
id2 (Foreign Key)
I want to select the artist teams where their favorite genres are the same.
My work so far is
SELECT *
FROM Two INNER JOIN One
WHERE ( ).
Im confused as to what to put in the WHERE statement.
I have no idea how to compare the values of the artist's genres to each other!
pseudo code for WHERE:
retrieve id#1's favourite genre
retrieve id#2's favourite genre
compare them
if equal display the related entity from table Two
I've searched for a while looking for a solution and I can't find anything
just like this, I believe it could be a bit a syntax that im missing.
Thanks for any help!
You need multiple joins to the "artists" table:
select t.*, a1.genre
from teams t join
artists a1
on t.id1 = a1.id join
artists a2
on t.id2 = a2.id and a2.genre = a1.genre;

Combine data from 2 "strange" tables

Having the following Schema
(ER of DataBase)
I am trying to create a query that
will show the title(Movies.Title) along with each movie's genre(movie_Genres.movie_genre) for each movie that..
that have been seen in (a) a specific time period (lets say 2-3 days for ex. We can take those days from the Tickets.ticket_date) (b) by Male Customers(Customer.customer_sec) and (c) got rated more than 4 (rated_customerRation) by those customers.
I can get as close as the following query:
SELECT
`movie_title`, `movie_Genres`.`movie_genre`
FROM
`Movies`
INNER JOIN
`movie_Genres` ON `mg_movie` = `movie_ID`
INNER JOIN
`Rated` ON `rated_movie_ID` = `movie_ID`
WHERE `rated_customerRatio` > 4 AND
UNION
(SELECT
`customer_sex`, `rated_customerRatio`
FROM
`Customer`
/* INNER JOIN
`cinema`.`Rated` ON `Rated`.`rated_customer_tabID` = `Customer`.`customer_tabID`
*/
INNER JOIN
`cinema`.`Tickets` ON `Tickets`.`ticket_customer_tabID`=`Customer`.`customer_tabID`
WHERE
`customer_sex` LIKE 'Male'
/* AND rated_customerRatio > 4 */
AND `Tickets`.`ticket_date` > '2016-02-16')
GROUP BY `movie_title`;
Also I am thinking that I will have trouble, cause one movie can have more than one Genre, and I don't want double lines, for the same movie, in my outcome.
Any help will be taken into serious regards!
use a WHERE movie.ID IN (Select movie.id...) query to have unusual query relationships. i.e. if movie.id can be related to tickets
WHERE MovieID IN
(
SELECT
MovieID
FROM
MovieTable
LEFT JOIN TICKETS ON MovieID = TICKETS.movieID
LEFT JOIN CUSTOMER ON TICKETS.ID = CUSTOMER.ID
WHERE
CUSTOMER.customer_sex LIKE 'Male'
AND Tickets.ticket_date > '2016-02-16')
)
I dont know your DB schema but that should give you a rough idea on one way of sorting based on viewership of moves from tickets? 1 ticket should have 1 movie ID and 1 customer, so the relationship is pretty easy to figure out

MYSQL self referential logic with a self join

I have a table called friends which has id and name and a self join table called friendship which stores the relationship which includes friend_id and friend2_id .
how do i get the names of related friends if a name of a particular frnd is given
example
id name
1 jack
2 kurt
3 jim
and
friendship
f_id f1_id
1 3
So if i give 'jack' i should get jim back
You could do this in one query or two queries, depending on what you want to accomplish.
A simple one could be:
SELECT
f_id,
f1_id
FROM
friendship
WHERE
f_id=1
OR
f1_id=1
And then you can get the specific friends with a statement like:
SELECT name FROM people WHERE id IN(2,3)
Alternative is a self join but the hard part here is that your id might be in both f_id and f1_id so that would need some UNION command or something like (untested):
SELECT
p1.name,
p2.name,
FROM
friendship
INNER JOIN
people AS p1
ON friendship.f_id = people.id
INNER JOIN
people AS p2
ON friendship.f1_id = people.id
WHERE
p1.id=1 OR p2.id=1
I would thoroughly check the speed of these options since they are quite heavy on huge amounts of records. If you measure you need more performance try some alternative. For example when you always put the smallest people.id in f_id and the bigger one in f1_id you might run 2 queries which you union. Alternative is to denormalize a small bit to cache the results if you need them frequently.
It would save you lots of joings for example if you would add the names into the friendship table:
SELECT
f_id,
f1_id,
f_name,
f1_name
FROM
friendship
WHERE
f_id=1
OR
f1_id=1