Reputation: 450
Say I had a database storing data from recent football games with my friends. I'd store the names of my friends in each row in no particular order. How could I pull that data back out without having to go through each row looking for each value in every column?
Here's an example table:
gameID player1 player2 player3 .......
1 John Chance Gordon
2 Jim Gordon John
3 Derek Chance Richard
How could I select the rows that John played in just based on if he was in any column? I'm planning on putting them into a PHP array and counting their appearances. What is the most efficient way of checking every columns without making something like:
$playerarray=array{'Derek','John','Gordon','Richard','Jim','Chance',....}
foreach($playerarray as $key => $value){
//Is this even horribly inefficient?
$sql = mysql_query(SELECT * from game_table WHERE player1='$value' OR player2='$value' OR player3='$value'...)
}
Upvotes: 2
Views: 265
Reputation: 753
The SQL statement that you need is the following:
SELECT * FROM game_table WHERE CONCAT_WS(',', player1, player2, player3) LIKE '%John%'
This query will return all fields of the rows where John comes in: first the 3 players' columns are concatenated with commas, and then searched whether John is in it.
If you would just want to count them:
SELECT COUNT(DISTINCT gameID) as numberofmatches FROM game_table WHERE CONCAT_WS(',', player1, player2, player3) LIKE '%,John,%' OR CONCAT_WS(',', player1, player2, player3) LIKE 'John,%' OR CONCAT_WS(',', player1, player2, player3) LIKE '%,John'
Or if you want a list of all the players:
(SELECT DISTINCT player1 AS player FROM game_table) UNION
(SELECT DISTINCT player2 AS player FROM game_table) UNION
(SELECT DISTINCT player3 AS player FROM game_table)
ORDER BY player
You could also combine this with the previous, which gives me exactly what you want (I think):
SELECT player,count(distinct gameID) as numberofgames FROM game_table t1 JOIN ((SELECT DISTINCT player1 AS player FROM game_table) UNION (SELECT DISTINCT player2 AS player FROM game_table) UNION (SELECT DISTINCT player3 AS player FROM game_table) ORDER BY player) t2 WHERE t2.player=t1.player1 OR t2.player=t1.player2 OR t2.player=t1.player3 GROUP by t2.player
This returns you a table with the names of all the different players, including the number of games they played !
If you want to select only a certain person (John), do the following:
SELECT player,count(distinct gameID) as numberofgames FROM game_table t1 JOIN ((SELECT DISTINCT player1 AS player FROM game_table) UNION (SELECT DISTINCT player2 AS player FROM game_table) UNION (SELECT DISTINCT player3 AS player FROM game_table) ORDER BY player) t2 WHERE (t2.player=t1.player1 OR t2.player=t1.player2 OR t2.player=t1.player3) AND t2.player='John' GROUP by t2.player
Upvotes: 1
Reputation: 1519
You could use the 'IN' clause like:
$playerarray = array{'Derek','John','Gordon','Richard','Jim','Chance',....};
$sql = mysqli_query("SELECT * from game_table WHERE player1 IN (" . $value . ") OR player2 IN (" . $value . ") OR player3 IN (" . $value . ") OR player4 IN (" . $value . ")");
Also, don't use mysql but mysqli functions as the first one is depricated.
Alternatively, or rather preferably, if there's alot of players (meaning: alot of columns) you would be better of changing the design of your database. Normalization should make things easier here.
Upvotes: 0