MySQL Multi Join - php

I had a look at the other answers in relation to mysql join and am still a little confused as to whether i'm using it right for the right instance.
I have a query that I need to perform over multiple tables at the same time and keep getting told that my statement is ambiguous.
I have 4 tables... trecord, thours, torders and tphotos
The trecord table has it's own autonumber called bid, and all the other tables have their own autonumber as well as a bid column. The trecord table will only ever have one record that needs to be retrieved at a time as does the thours table, but the torders and tphotos table will more often than not have multiple records in them that will tie back to the trecord to always show the company info.
How can I bring together all the information from trecord and thours as well as all of the information from torders and tphotos that match the bid?
$id = isset($_POST['bid']) ? $_POST['bid'] : isset($_GET['bid']) ? $_GET['bid'] : null;
$sql = "SELECT * FROM torders
INNER JOIN trecord ON torders.bid=trecord.bid
INNER JOIN thours ON thours.bid=trecord.bid
INNER JOIN tphotos ON tphotos.bid=trecord.bid
FROM WHERE bid='" . mysql_real_escape_string($id) . "'";

If every table has a 'bid' column, you need to be more specific as to which one you are running your where clause against.

Related

Multi-Table, Multi-WHERE and SELECT MySQL query

So, I am trying to select some data from 4 tables using a query I have attempted to throw together.
SELECT *
FROM cards
LEFT JOIN cards_viewers ON cards.card_id = cards_viewers.card_id
(SELECT *
FROM folders
WHERE folder_id = cards.card_folderID)
(SELECT user_firstName,
user_lastName,
user_avatar
FROM user_data
WHERE user_id = cards_viewers.user_id)
WHERE cards_viewers.user_id = '.$u_id.'
ORDER BY cards.card_lastUpdated DESC
Basically, the query selects data from the four tables depending on the user_id in table user_data. I have attempted to initially fetch all data from the tables cards, and cards_viewers, and have went on to use this data to select values from the other tables (user_data and folders).
The query is wrong, I know that. I have learnt the majority of basic MySQL, but I am still struggling with more complex queries like the one I am trying to write now. What query can I use to select the data I want?
Links to any documentation to parts of queries would prove very useful in helping me learn how to create queries in future, rather than just relying on StackOverflow.
Many thanks.
You don't need "MULTI-WHERE" but multiple joins, you just need to keep doing joins until you get the tables you need.
Here's an example:
SELECT *
FROM cards LEFT JOIN cards_viewers
ON cards.card_id = cards_viewers.card_id
LEFT JOIN folders
ON folders.folder_id = cards.card_folderID
LEFT JOIN user_data
ON user_id = cards_viewers.user_id
WHERE cards_viewers.user_id = '.$u_id.'
ORDER BY cards.card_lastUpdated DESC
To custom the fields you want to get just change * for the name of the field being careful about ambiguous column naming.
For further information check MySql Joins. Hope this helped you :)

SUM value from query changes when i add inner join to the query

$sql = mysql_query("SELECT totals.*, sum(totals.payments) as total_payments
FROM totals
INNER JOIN users
GROUP BY totals.idseller;");
When i add the INNER JOIN the sum value is changed. Why?
In my SQL table i have one record in totals width this value: 8943.09 but when i do the some the result is giving me this value: 44715.45
What i am doing wrong?
$sql = mysql_query("SELECT totals.*, sum(totals.payments) as total_payments FROM totals
INNER JOIN users ON totals.idseller = users.idseller
GROUP BY users.UserName;");
Use this Hope this will help you.
When you INNER JOIN to another table, the returned data set is modified to only include rows that exist in both tables. In this case it is likely that there are rows in 'totals' that do not have a matching row in users - either the totals.idseller field might accept null values, or data has become orphaned when matching users have been deleted or edited.
If you want all data in 'totals' regardless of matching user you would user a LEFT JOIN instead in ms-sql, I suspect a similar approach will work in my-sql
You should give an "on" based on the ids. Such as like
inner join users on users.id = totals.idseller
Otherways the sql server will combine all possible rows in the tables, which is most cases not what you wish.
Because when you are adding inner join in your SQL Query, it means you are selecting the data which is common in both the tables.
EX:
SELECT * FROM TABLE_A
INNER JOIN TABLE_B
ON TABLE_A.ID = TABLE_B.ID
If you are joining users table which contains 5 records. By joining table, as there is no any column mapping, this sum-up 5 times and this is reason for showing different values.
Please let me know something wrong in it.
Thanks,
Umehs

Tricky MySQL query involving NOT IN

I have two tables that I am joining together in order to get results.
One table contains a list of assessments with a unique ID (assessments), whilst the other table (staff_to_assessments) contains a list of assessments that are assigned to staff members. An example record for this table would contain the Staff member unique ID, and the assignment unique ID. This shows that a user has been linked to an assignment.
I have written a function which only grabs assessments from the assessment table where they have not been assigned to a staff member in staff_to_assessment table. This is to populate a drop-down box on the front end where these remaining assessments can be assigned to a staff member if required, therefore I don;t want to show any that are already assigned.
MySQL query is as follows:
SELECT * FROM assessments a
LEFT JOIN staff_to_assessment s2a ON a.assessment_id = s2a.assessment_id
WHERE a.assessment_id NOT IN
(SELECT assessment_id FROM staff_to_assessment WHERE staff_id = '" . (int)$options['staffId'] . "')";
This doesn't seem to generate the response I need. Can anybody see where I have gone wrong?
Thanks!!
I think your query is working too hard. You just need to find rows where there is no match to the left outer join:
SELECT a.*
FROM assessments a LEFT JOIN
staff_to_assessment s2a
ON a.assessment_id = s2a.assessment_id
WHERE s2a.assessment_id is null;
You don't need to use both a left join and a not in clause.
Queries like NOT IN [subquery] can (and should) always be rewritten as a LEFT JOIN.
SELECT a.*
FROM assessments a
LEFT JOIN staff_to_assessment s2a USING (assessment_id) -- equivalent to "ON a.assessment_id = s2a.assessment_id", as both columns have the same name
WHERE staff_id IS NULL
This is equivalent to:
SELECT a.*
FROM assessments a
WHERE a.assessment_id NOT IN (SELECT assessment_id FROM staff_to_assessment)
Both are usually optimised away to the same execution plan, but the former is preferable as it tends to produce quicker queries.

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.

Categories