Searching multiple tables in MySQL database - php

I have several different tables in my database(mySQL).
Here are the relevant coumns for the tables
table_tournaments
tournamentId
tournamnetName
tournamentStatus
table_tournament_results
tournamentId
playerId
playerName
playerRank
tournamnetParticipants
table_players
playerId
playerName
The tournaments table contains the information about the tournament, the tournament results table shows the results from that table
I want to search the tournaments table by name and then with the returned results get the information from the tournament results table.
SELECT * FROM `tournaments` `WHERE` `tournamentName` LIKE "%Query%"
I'm not sure how to go about this, maybe I need to do something via PHP, any and all help is appreciated.

You can get the results you want with a join operation.
This is an example of an outer join, returning all rows from t that have the string 'foo' appearing as part of tournament_name, along with any matching rows from r.
A relationship between rows in the two tables is established by storing a common value in the tournamentId column of the two tables. The predicate in the ON clause specifies the condition that determines if a row "matches".
SELECT t.tournamentId
, t.tournamentName
, t.tournamentStatus
, r.playerId
, r.playerName
, r.playerRank
FROM table_tournaments t
LEFT
JOIN table_tournament_results r
ON r.tournamentId = t.tournamentId
WHERE t.tournament_name LIKE '%foo%'
ORDER
BY t.tournamentId
, r.playerId
The t and r that appear after the table names are table aliases, we can qualify references to the columns in each table by prefacing the column name with the table alias and a dot. This makes the column reference unambiguous. (In the case of tournamentId, MySQL doesn't know if you are referring to the column in t or r, so we qualify it to make it explicit. We follow this same pattern for all column references. Then, someone reading the statement doesn't need to wonder which table contains the column playerId.

Your Query may be like this
SELECT a.*, b.tournamnetName FROM table_tournament_results a
left join table_tournaments on a.tournamentId=b.tournamentId
WHERE b.tournamnetName LIKE "%Query%"

Related

mysql select across 2 tables - only include rows from 1 if match value in another

I've built a maintenance database for a client with multiple tables that works fine, but now they want to be able to get reports and I'm having trouble creating a select statement across 2 tables.
A user can search repair type, start/end date and location...no issue at all returning results of repair type between 2 dates (all held in the same table), but the tables for different types of repair don't store the location info, that is held against info in the vehicle info table.
So on 1 table I can query something like:
SELECT fid from cm_repair where start_date >= '$date1' AND end_date <= '$date2'
and on the other table I can have:
SELECT id from cm_fleet where location='$loc'
Is there anyway I can combine these so that I only get rows where id and fid match?
You can use an INNER JOIN:
SELECT fid
from cm_repair as t1
join cm_fleet as t2 on t1.fid = t2.id and location='$loc'
where start_date >= '$date1' AND end_date <= '$date2'
Check this link.
Inner, left, and right join's are common options for combining tables that you might be needing here.
Inner will bring in all valid rows and selected columns from BOTH tables. Essentially if the ID you are joining is present in one table, but not the other, you could end up with columns with null values.
Left and right are similar and a bit faster at processing than the Inner since less data is returned (depending on your query and statements). Essentially it'll return all valid rows and selected columns from the left and right table, BUT if the ID that you are joining on is not in the other side of the join, that row of data will not be returned, therefore no null values.
Thanks, will try all this - however we've discovered a flaw in the way the tables are setup anyway and need to edit to include a location column in the repair table, so that will make it all much easier to search as well.

How to get value from one table column when two columns of the same name exist in an sql join

I am currently faced with the problem of trying to get a value when I have joined two tables with columns of the same name eg: table1.date and table2.date (date is different in each table) how would I get the "date" of table 1 in this instance.
I am currently running
while($row = $mysqliquery->fetch_object()) {
is there any way that I could use some form of syntax to retrieve the date from table 1 within the following code
$row->date eg $row->table1.date or something
If not how else would I be able to accomplish this?
Thanks.
You should differentiate between 2 columns with the same name by using an alias for one or both of the 2 columns in the query like this
SELECT a.`date`, b.`date` as b_date
FROM table1 a
JOIN table2 b ON a.id = b.a_id
WHERE some specific criteria
Now when your retrieve the ROW each date has its own unique name i.e.
$row->date;
$row->b_date;
I was thinking more along the lines of this ( ficticious ) pseudo sql
select a.`account_id`, a.`date` as 'account_date', u.`date` as 'signup_date'
from `accounts` a
left outer join `users` u on u.`uid`=a.`uid`
Each table has a column called date but in the sql they are each referenced with a unique alias. You cannot have two columns in the same query with the same name or you'll get errors, so you give them an alias. The tables are also aliased in this code - it really helps simplify things in my opinion... Anyway, just a quick example to illustrate how you might approach this - others may have a different approach from which I might learn new tricks

Msql Inner Join Query Dilemma - Need Joined Auto Increment Value

I have two mysql tables that I am querying together and the query works fine. The tables are car and requests
The problem is that i need both the auto increment id's and it only gives me one.
The one it gives me is not the joined tabled.
Here is my query so far
SELECT * FROM `car` INNER JOIN `requests` ON `car`.`make_id` = `requests`.`make_id` WHERE `car`.`user_id` =21
I just need to someway get the auto increment id of the requests table.
As always stack exchange is the best place to come for answers so thanks in advance!
Just specify your query as this and you'll get both but with different names:
SELECT `car`.id AS car_id, `requests`.id AS request_id, *
FROM `car`
INNER JOIN `requests` ON `car`.`make_id` = `requests`.`make_id`
WHERE `car`.`user_id` =21
Note that you will still have an ID column which SHOULD be the requests.id, just diregard it and use car_id and request_id...
When you have to join tables and table contains same name than it creates an ambiguous situation. So always use table name or table alias with column name Like this
SELECT t.column
FROM table as t
OR
SELECT table.column
FROM table

Getting SQL result as nested array in PHP

I've a ('courses') table that has a HABTM relationship with ('instructors') table through another table...
I want to get the data of an instructor with all related courses in one query..
Currently, I have the following SQL:
SELECT *
FROM `instructors` AS `instructor`
LEFT JOIN `courses` AS `course`
ON `course`.`id` IN (
SELECT `course_id`
FROM `course_instructors`
WHERE `course_instructors`.`instructor_id` = `instructor`.`id`
)
WHERE `instructor`.`id` = 1
This SQL does what it should be doing, the only "problem" I have is that I get multiple rows for each joined rows.
My question is:
Can I get the result I want in one query? Or do I have to manipulate the data in PHP?
I'm using PHP and MySQL.
Each record of a query result set has the same format: same number of fields, same fields, same order of fields. You cannot change that.
SELECT *
FROM instructors AS instructor
LEFT JOIN
course_instructors
ON
instructor.id= course_instructors.instructor_id
LEFT JOIN
courses
ON
course_instructors.course_id = course.id
WHERE instructor.id = 1
This assumes the PK of course_instructors is (instructor_id,course_id)
Explanation of query:
First join + WHERE make sure you get the relevant instructor
Second join matches ALL the entries from the course_instructor table that belongs to this instructor. If none found, will return one row with NULL in all fields
Last join matches all relevant courses from the entries found from course_instructor If none would will return one record with NULL in all fields.
Again: important to use the right constraints to avoid duplicate data.
That's the nature of relational databases. You need to get the instructor first and then get the related courses. That's how I would do it and that's how I've been doing it. I'm not sure if there is a "hack" to it.

Joining multiple (4) tables in MYSQL

I have four tables I want to join and get data from. The tables look something like...
Employees (EmployeeID, GroupID[fk], EmployeeName, PhoneNum)
Positions (PositionID, PositionName)
EmployeePositions (EployeePositionID, EmployeeID[fk], PositionID[fk])
EmployeeGroup (GroupID, GroupName)
[fk] = foreign key
I want to create a query that will return all the information about an employee(given by EmployeeID). I want a query that will return the given employees Name, position(s), and group in one row.
I think it needs to involve joins, but I am not sure how to format the queries. MYSQL's manual is technical beyond my comprehension. I would be very grateful for any help.
It seems you have trouble with SQL, in general, rather than with mySQL in particular. The documentation of mySQL provides details about the various SQL expressions, but generally assume some familiarity with SQL. To get a quick start on SQL you may consider this W3schools.com primer.
The query you need is the following.
SELECT EmployeeName, PositionName, GroupName
FROM Employees E
LEFT JOIN EmployeePositions EP ON EP.EmployeeID = E.EmployeeID
LEFT JOIN Positions P ON P.PositionID = EP.PositionId
LEFT JOIN EmployeeGroup EG ON EG.GroupId = E.GroupId
WHERE E.EmployeeId = some_value
A few things to note:
The 'LEFT' in 'LEFT JOIN' will result in producing NULL in lieu of PositionName or GroupName when the corresponding tables do not have a value for the given FK. (Should only happen if the data is broken, say if for example some employees have GroupId 123 but somehow this groupid was deleted from the EmployeeGroup table.
The query returns one line per employee (1). You could use an alternative search criteria, for example WHERE EmployeeName = 'SMITH', and get a listing of all employees with that name. Indeed without a WHERE clause, you'd get a list of all employees found in Employees table.
(1) that is assuming that each employee can only have one position. If somehow some employees have more than one position (i.e. multiple rows in EmployeePositions for a given EmployeeID), you'd get several rows per employee, the Name and Group being repeated and a distinct PostionName.
Edit:
If a given employee can have multiple positions, you can use the query suggested by Tor Valamo, which uses a GROUP BY construct, with GROUP_CONCAT() to pivot all the possible positions in one single field value in the returned row.
SELECT e.EmployeeID, e.EmployeeName, e.PhoneNum,
g.GroupName, GROUP_CONCAT(p.PositionName) AS Positions
FROM Employees e
LEFT JOIN EmployeeGroup g ON g.GroupID = e.GroupID
LEFT JOIN EmployeePositions ep ON ep.EmployeeID = e.EmployeeID
LEFT JOIN Positions p ON p.PositionID = ep.PositionID
WHERE e.EmployeeID = 1
GROUP BY e.EmployeeID
Returns positions in a comma separated string on one row.

Categories