Joining 3 tables with mySQL with 1 query - php

This has been asked and answered in different instances but all that I've seen doesn't quite work for my problem.
PROBLEM: I have 3 tables I need to pull data from at the same time to compare and retrieve information from. All 3 tables contain an 'email' column. Now, a user's email from table1 may match same user's email in both table2 AND table3, depending on user's status. OR an email from table1 will ONLY match either an email in table2 or table3, depending on user's status again. For example, a user may have a red status (user will show in table2), a blue status (user will show in table3), or both, red and blue (user will show in both, table2 and table3).
WHAT IS NEEDED: an email from table1 needs to be compared to email in table2 and table3 and return a region value for a given user, which is recorded in table2 and table3 but not in table1. I know. Delightful data architecture! Either way, I was able to JOIN table1 to table2 very successfully but I am not sure how to slap on a JOIN with table3.
Here's the query for 2 tables:
SELECT * FROM table1
INNER JOIN table2
ON table2.email = table1.email
WHERE month = 'numberHere' ORDER BY submitdate DESC
When I simply add another INNER JOIN my code doesn't break per say but it doesn't give me any rows to be displayed either. So the code below doesn't work despite the many working examples from the web:
SELECT * FROM table1
INNER JOIN table2
ON table2.email = table1.email
INNER JOIN table3
ON table3.email = table2.email
WHERE month = 'numberHere' ORDER BY submitdate DESC

To match the row from table1 in any case and the rows of other tables only if they are, you have to use LEFT JOIN, joining table2 and table3 with table1 (not table2 with table1 and table3 with tabel2):
SELECT * FROM table1
LEFT JOIN table2
ON table2.email = table1.email
LEFT JOIN table3
ON table3.email = table1.email
In this way you select values from table1 even without a match in other tables.
See more about SQL Joins: Different SQL Joins

You need to use LEFT JOIN, so that the joins will succeed even if there's no matching row in one of the tables.
SELECT * FROM table1
LEFT JOIN table2
ON table2.email = table1.email
LEFT JOIN table3
ON table3.email = table2.email
WHERE month = 'numberHere'
AND (table2.email IS NOT NULL OR table3.email IS NOT NULL)
ORDER BY submitdate DESC
The additional conditions filter out rows that have no match in either of the tables.

Related

MYSQL count different values of a row with distinct value of another row

Using the below query i'm able to get the count of male and female of each municipality but the problem is municipalities come in duplicate entries, I want all same municipalities to come in one row and all their male and females be counted all together. Someone please help me :(
I need the data of Gender and Training Location columns of the table2 and it is inner join with table1 because for each record of table1 I have many records in table2.
Please refer to the below picture of what i currently get through this query
Select
(Select count(*) from table2 where gender='Male' and table1.ID=table2.ID) AS Male,
(Select count(*) from table2 where gender='Female' and table1.ID=table2.ID) AS Female,
Training_Location
from table2
INNER JOIN table1 ON table1.id = table2.ID
WHERE table1.Training_Start_Date BETWEEN '$StartDate' and '$EndDate'
group by table1.ID
I think you want to remove the JOIN in the outer query:
select t1.id, t1.Training_Location
(Select count(*) from table2 t2 where t2.gender='Male' and t1.I D= t2.ID) AS Male,
(Select count(*) from tbl_ind1_sub tis where tis.gender ='Female' and t1.ID = tis.ID) AS Female,
from table1 t1 ON table1.id = table2.ID
where t1.Training_Start_Date between ? and ?;
It seems really strange to me that males and females would be in separate tables. But that is how your question is structured.
Note that no group by is needed in the outer query, assuming the id is unique (a reasonable assumption).
Also, do not munge queries with constants. Pass them into the query as parameters.
If you decide that the tables in the subquery are the same table, ask a new question. This question clearly has them as separate tables.

PDO JOIN LEFT - fetch result - no result [duplicate]

I'm doing some maintenance work on a database application and I've discovered that, joy of joys, even though values from one table are being used in the style of foreign keys, there's no foreign key constraints on the tables.
I'm trying to add FK constraints on these columns, but I'm finding that, because there's already a whole load of bad data in the tables from previous errors which have been naively corrected, I need to find the rows which don't match up to the other table and then delete them.
I've found some examples of this kind of query on the web, but they all seem to provide examples rather than explanations, and I don't understand why they work.
Can someone explain to me how to construct a query which returns all the rows with no matches in another table, and what it's doing, so that I can make these queries myself, rather than coming running to SO for every table in this mess that has no FK constraints?
Here's a simple query:
SELECT t1.ID
FROM Table1 t1
LEFT JOIN Table2 t2 ON t1.ID = t2.ID
WHERE t2.ID IS NULL
The key points are:
LEFT JOIN is used; this will return ALL rows from Table1, regardless of whether or not there is a matching row in Table2.
The WHERE t2.ID IS NULL clause; this will restrict the results returned to only those rows where the ID returned from Table2 is null - in other words there is NO record in Table2 for that particular ID from Table1. Table2.ID will be returned as NULL for all records from Table1 where the ID is not matched in Table2.
I would use EXISTS expression since it is more powerful, you can e.g. more precisely choose rows you would like to join. In the case of LEFT JOIN, you have to take everything that's in the joined table. Its efficiency is probably the same as in the case of LEFT JOIN with null constraint.
SELECT t1.ID
FROM Table1 t1
WHERE NOT EXISTS (SELECT t2.ID FROM Table2 t2 WHERE t1.ID = t2.ID)
SELECT id FROM table1 WHERE foreign_key_id_column NOT IN (SELECT id FROM table2)
Table 1 has a column that you want to add the foreign key constraint to, but the values in the foreign_key_id_column don't all match up with an id in table 2.
The initial select lists the ids from table1. These will be the rows we want to delete.
The NOT IN clause in the where statement limits the query to only rows where the value in the foreign_key_id_column is not in the list of table 2 ids.
The SELECT statement in parenthesis will get a list of all the ids that are in table 2.
Let we have the following 2 tables(salary and employee)
Now i want those records from employee table which are not in salary.
We can do this in 3 ways:
Using inner Join
select * from employee
where id not in(select e.id from employee e inner join salary s on e.id=s.id)
Using Left outer join
select * from employee e
left outer join salary s on e.id=s.id where s.id is null
Using Full Join
select * from employee e
full outer join salary s on e.id=s.id where e.id not in(select id from salary)
Where T2 is the table to which you're adding the constraint:
SELECT *
FROM T2
WHERE constrained_field NOT
IN (
SELECT DISTINCT t.constrained_field
FROM T2
INNER JOIN T1 t
USING ( constrained_field )
)
And delete the results.
From similar question here MySQL Inner Join Query To Get Records Not Present in Other Table I got this to work
SELECT * FROM bigtable
LEFT JOIN smalltable ON bigtable.id = smalltable.id
WHERE smalltable.id IS NULL
smalltable is where you have missing records, bigtable is where you have all the records. The query list all the records that not exist in smalltable but exists on the bigtable. You could replace id by any other matching criteria.
I Dont Knew Which one Is Optimized (compared to #AdaTheDev
) but This one seems to be quicker when I use (atleast for me)
SELECT id FROM table_1 EXCEPT SELECT DISTINCT (table1_id) table1_id FROM table_2
If You want to get any other specific attribute you can use:
SELECT COUNT(*) FROM table_1 where id in (SELECT id FROM table_1 EXCEPT SELECT DISTINCT (table1_id) table1_id FROM table_2);
You could opt for Views as shown below:
CREATE VIEW AuthorizedUserProjectView AS select t1.username as username, t1.email as useremail, p.id as projectid,
(select m.role from userproject m where m.projectid = p.id and m.userid = t1.id) as role
FROM authorizeduser as t1, project as p
and then work on the view for selecting or updating:
select * from AuthorizedUserProjectView where projectid = 49
which yields the result as shown in the picture below i.e. for non-matching column null has been filled in.
[Result of select on the view][1]
You can do something like this
SELECT IFNULL(`price`.`fPrice`,100) as fPrice,product.ProductId,ProductName
FROM `products` left join `price` ON
price.ProductId=product.ProductId AND (GeoFancingId=1 OR GeoFancingId
IS NULL) WHERE Status="Active" AND Delete="No"
SELECT * FROM First_table
MINUS
SELECT * FROM another
How to select rows with no matching entry in Both table?
select * from [dbo].[EmppDetails] e
right join [Employee].[Gender] d on e.Gid=d.Gid
where e.Gid is Null
union
select * from [dbo].[EmppDetails] e
left join [Employee].[Gender] d on e.Gid=d.Gid
where d.Gid is Null

SQL JOIN to get two records for each row

I have two tables, say
TABLE: Transactions
COLUMNS: sender_id, receiver_id, value
and
TABLE: Users
COLUMNS: user_id, username
Is it possible to make a SQL statement to JOIN two rows from the users table for each record in the transactions table? So for each result row, I should have two usernames from the users table, but with two different aliases. How to achieve this?
Thanks
Assuming sender_id and receiver_id are references to a user_id, and assuming that user_id is UNIQUE in the Users table... yes.
Join to the Users table twice.
For example:
SELECT t.sender_id
, t.receiver_id
, t.value
, s.user_id AS sender_user_id
, s.username AS sender_username
, r.user_id AS receiver_user_id
, r.username AS receiver_username
FROM `Transactions` t
LEFT
JOIN `Users` s ON s.user_id = t.sender_id
LEFT
JOIN `Users` r ON r.user_id = t.receiver_id
ORDER BY 1,2,3
The query is using outer joins... the row from Transactions will be returned if receiver_id or sender_id doesn't match a row in the Users table.
The keyword LEFT can be removed to change that behavior, so a row will be returned only if there is a matching row in Users for both sender_id and receiver_id.
You have the right idea, by talking about aliases. You need two joins:
select us.username, ur.username, t.value
from transactions t left join
users us
on t.sender_id = us.user_id left join
users ur
on t.receiver_id = ur.receiver_id;
left join is just in case one of the values does not match.

How to link Id from one table with another

i have spent the last 2 days going over this problem trying to work it out.
i have two tables
one is the user_login and it has a row called user_id the other is agedcare and it has a row called id
i have tried to get the 2 to link together
i want to be able to update the agedcare using the id from user_login as the main id
$query = "SELECT id FROM agedcare INNER JOIN user_id ON login_users = login_users.user_id WHERE login_users.user_id = '$id'"
The format is something more like..
SELECT id,name,age
FROM Table1
INNER JOIN Table2
ON Table1.Field=Table2.Field
Another way to simplify the select statement (so that you avoid using the table names throughout) is to "rename" the table right after you name it. For example, the line that has "FROM Table1 T1" - the T1 immediately after the table name is "renaming" the table allowing you to shorten the table name when you need to refer to it. In addition, you can use the t1 and t2 identifiers when selecting the fields.
SELECT t1.id,t1.name,t2.age
FROM Table1 T1
INNER JOIN Table2 T2
ON T1.Field=T2.Field
Check your format of join, it must be like this
SELECT * FROM t1 as a LEFT JOIN t2 as b ON a.id=b.id where user_id = 'id'

How to get a LEFT JOINED query result without all of the NULLs

I am LEFT JOINing multiple tables as such:
SELECT * FROM table1
LEFT JOIN table2 ON table1.id = table2.fid
LEFT JOIN table3 ON table1.id = table3.fid
LEFT JOIN table4 ON table1.id = table4.fid
LEFT JOIN table5 ON table1.id = table5.fid
LEFT JOIN table6 ON table1.id = table6.fid
WHERE table2.id = '5184'
Reason being is simply because I tried regular JOIN and no results are returned unless at least one record exists in tables1-6 which is often not the case. As it stands this returns the info I want, but the problem is that a lot of the field names repeat and when I do a 'mysql_fetch_array()' in PHP it hides any field with a duplicate name.
What type of query can I do to avoid this? At the very least, how do I construct the query such that it doesn't include all the double fields which are NULL?
Thanks
I can't help but notice that you aren't selecting anything from your left joined tables. It's my understanding that joins are typically used to pull data from secondary tables where something in those tables matches a field in the primary table. I pulled this example from W3 schools:
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
LEFT JOIN Orders
ON Persons.P_Id=Orders.P_Id
ORDER BY Persons.LastName
And unless this is a typo, you are selecting everything from table 1 where an id column = 5186 in table 2.
You state that your query returns the info you want, but with many nulls and overwritten values. To fix this, I would restructure your query to follow the typical format shown above, and make sure you have a proper use of the left join statement.
EDIT AFTER OP COMMENTS:
You are naming a row id from table2, so I assume you should start by pulling fid from table 2 where table2.id = 5186, then left join from the other tables where table1.id = table2.fid.
SELECT table2.fid, table1.id, table3.id, [add other tables here, and revise field names to select the ones you want]
FROM table2
LEFT JOIN table1 ON table1.id = table2.fid
LEFT JOIN table 3 ON table3.fid = table1.id
[add left joins to other tables here]
WHERE table2.id = '5186'
If this doesn't help, I suggest being more specific towards what information the tables hold, and what you are searching for. A little more detail may help us help you.

Categories