Join a table based on first table's content - php

I am trying to come up with a query where a 3rd table will join another two. The problem is there are different versions of this first table and I need the query to look at a column in table 1 and then choose the correct table to join but the resulting query must return all rows in table 1 just join an extra table 3 to specific rows which meet the WHERe clause. Is this even possible?
Example:
Table 1 = User
Table 2 = Banners
Table 3 = UserSettings OR AdminSettings OR Nothing
Query would say...
WHERE User.rank='admin' LEFT JOIN AdminSettings
WHERE User.rank='user' LEFT JOIN UserSettings
My current query is this:
$query = "SELECT * FROM Users as U WHERE U.user_id = :id ";
$query .= "LEFT JOIN Banners as B ON U.banner_id = B.banner_id ";
$query .= "LEFT JOIN AdminSettings ON U.server_id = AdminSettings.user_id WHERE U.rank='Admin' ";
$query .= "LIMIT 1";
Problem is that it only shows rows that have User.rank='admin' and does not show the rows where User.rank='user' rest.

Join table3 twice and use CASE within the select statement
SELECT a.*,
b.*
CASE WHEN a.rank = 'admin'
THEN c.user_ID -- gets value from AdminSettings
ELSE d.user_ID -- gets value from UserSettings
END as ColName1,
CASE WHEN a.rank = 'admin'
THEN c.colName -- gets value from AdminSettings
ELSE d.colName -- gets value from UserSettings
END as ColName2
FROM users a
INNER JOIN banners b
ON a.banner_id = b.banner_id
LEFT JOIN AdminSettings c
ON a.server_ID = c.user_ID
LEFT JOIN UserSettings d
ON a.server_ID = d.user_ID

Try using a IF clause in the fields list, like this:
$query = "SELECT field1, field2, field3, IF(User.rank = 'admin', A.field, B.field)";
$query .= " FROM Users as U";
$query .= " LEFT JOIN Banners as B ON U.banner_id = B.banner_id";
$query .= " LEFT JOIN AdminSettings as A ON U.server_id = A.user_id";
$query .= " LIMIT 1";
Something like that should do the trick.

Related

MySQL INNER JOIN IN not getting right result

I have this query in my php and it seems to be fetching the wrong data set from my db.
$querystring = "
SELECT a.*,
b.itemcolour,
b.itemcolourname
FROM itemorders AS a
INNER JOIN catalogueitemscolour AS b
ON a.colourid = b.colourid
WHERE a.colourid IN(SELECT colourid
FROM itemorders
WHERE orderid = 61)
";
Here is a picture of my results
Can I know why it's not selecting the specific orderID of 61?
You can try below -
SELECT a.*, b.itemColour,b.itemColourName FROM itemorders
AS a INNER JOIN CatalogueItemsColour AS b ON a.colourID = b.colourID WHERE
a.orderID = 61
Because you are not putting condition on orderID, rather putting it on colorID. What you actually want is this condition: WHERE a.orderID = 61.

LEFT JOIN returns Not unique table/alias and Unknown column in 'on clause

I have PHP website with a table that prints out search results from a MySQL database via form with an input box. I use this SQL syntax and it works fine. I can search in one filed to get results from location.room_name and users.user_name:
SELECT:
SELECT computers.*, location.room_name AS location
FROM computers
LEFT JOIN location ON computers.location = location.id
LEFT JOIN users ON computers.user_1 = users.id".
" ".$searchCriterias."
ORDER BY id
WHERE:
$searchCriterias =
"WHERE
location.room_name LIKE '%".$s."%' OR
users.user_name LIKE '%".$s."%'
";
$s is the string from the search form.
The thing is that I have computers.user_1, computers.user_2 and computers.user_3 that all corresponds to users.id as in the syntax above. When I search for a username I would like to match it with user_1, user_2 and user_3 but I don't get it to work. I can only match it with one (in this case user_1).
I have tried to add LEFT JOIN users ON computers.user_2 = users.id and gets this error message: Not unique table/alias: 'users'
and...
LEFT JOIN users AS u1 ON computers.user_1 = users.id for all three and gets this messge: Unknown column 'users.id' in 'on clause'.
Why doesn't it work?
As you said you have 3 columns in computers table then try following while join. Also added GROUP BY to get unique result per user.
$query = "SELECT computers.*, location.room_name AS location
FROM computers
LEFT JOIN location ON computers.location = location.id
LEFT JOIN users ON (computers.user_1 = users.id
OR computers.user_2 = users.id
OR computers.user_3 = users.id ) ".
$searchCriterias . " GROUP BY users.id ORDER BY id";
Change your ON condition to IN statement :
SELECT computers.*, location.room_name AS location
FROM computers
LEFT JOIN location ON computers.location = location.id
LEFT JOIN users
ON ((users.id = computers.user_1) or
(users.id =computer.user_2 and not exists(select 1 from users t where t.id = computers.user_1)) OR
(users.id = computer.user_3 AND not exists(select 1 from users p where p.id IN(computer.user_2,computer.user_1))))".
" ".$searchCriterias."
ORDER BY id
Another option is to join against users 3 times, and amend your WHERE clause to check against 3 different tables.
Might need a DISTINCT to remove duplicates as I presume names can match multiple times.
This has the advantage over using an OR in the ON clause that it can still use indexes for the joins.
SELECT computers.*, location.room_name AS location
FROM computers
LEFT JOIN location ON computers.location = location.id
LEFT JOIN users users1 ON computers.user_1 = users1.id
LEFT JOIN users users2 ON computers.user_2 = users2.id
LEFT JOIN users users3 ON computers.user_3 = users3.id".
" ".$searchCriterias."
ORDER BY id
And the WHERE clause
$searchCriterias =
"WHERE
location.room_name LIKE '%".$s."%' OR
users1.user_name LIKE '%".$s."%' OR
users2.user_name LIKE '%".$s."%' OR
users3.user_name LIKE '%".$s."%'
";

MySQL LEFT JOIN example

I am working on a PHP file and MySQL.
On a file, I need to select records from three tables.
If a make a query with two tables:
$query_Recordset1 = "
SELECT * FROM tbgastos
LEFT JOIN tbconceptosgastos
ON tbgastos.tipoGasto = tbconceptosgastos.idConceptoGasto
LEFT JOIN tbobras
ON tbgastos.obra = tbobras.idObra
ORDER BY fecha DESC
";
it works fine, but if I try to make it with three tables:
$query_Recordset1 = "
SELECT * FROM tbgastos
LEFT JOIN tbconceptosgastos
ON tbgastos.tipoGasto = tbconceptosgastos.idConceptoGasto
LEFT JOIN tbobras
ON tbgastos.obra = tbobras.idObra
LEFT JOIN tbproveedores
ON tbgastos.proveedor = tbproveedores.nombreProveedor
ORDER BY fecha DESC
";
the third table (tbproveedores) records are not shown.
What am I doing wrong?
UPDATED
tbgastos
tbproveedores
In your table tbgastos, you have a foreign key of a int type (proveedor).
And you want it to match to the table tbproveedores. Don't you want to point on tbproveedores.idProveedor ?
$query_Recordset1 = "
SELECT * FROM tbgastos
LEFT JOIN tbconceptosgastos
ON tbgastos.tipoGasto = tbconceptosgastos.idConceptoGasto
LEFT JOIN tbobras
ON tbgastos.obra = tbobras.idObra
LEFT JOIN tbproveedores
ON tbgastos.proveedor = tbproveedores.idProveedor
ORDER BY fecha DESC
";

How to make a fancy mysql join that can join three tables and detect if one table DOESNT have my item

php mysql query
I have multiple linked tables - I also have a table that only creates and entry if certian conditions exist so I would like to add that into my query to avoid having to go through thousands of query searches looking for this special case
here is my current query
$query = "SELECT a.UUID FROM contract a
INNER JOIN geoPoint b ON a.customer_UUID = b.customerUUID
WHERE b.garcom_UUID = '$garbCom'
AND b.city_UUID = '$city'";
I then go through each item that was returned (in the thousands)
while ($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
$sentdata = getothertable($row['UUID']); //checks if the item is in the table
$sent = $sentdata ['senttoGarcom'];
if($sent == 0) //if it wasn't found add it to my list
{
array_push($Contracts,$row['UUID']);
}
}
instead of all that I would like to just make it one query - pseduo code something like this
$query = "SELECT a.UUID FROM contract a
INNER JOIN geoPoint b ON a.customer_UUID = b.customerUUID
INNER JOIN contract_sales c ON a.UUID = c.contractUUID
WHERE b.garcom_UUID = '$garbCom'
AND b.city_UUID = '$city' AND c.DOESNOTEXIST";
this way I dont have to return thousands I will only be returned the few that are not yet in the contract_sales table and I can go about my business...
Appreciate any help!
just check for NULL rows of c with a outer join
$query = "SELECT a.UUID FROM contract a
INNER JOIN geoPoint b ON a.customer_UUID = b.customerUUID
LEFT OUTER JOIN contract_sales c ON a.UUID = c.contractUUID
WHERE b.garcom_UUID = '$garbCom'
AND b.city_UUID = '$city' AND c.contractUUID IS NULL ";
I think this is a left outer join problem
Have a look at this example. You specifically need to have a check for a null in a column in the table which you want to find the missing row rof
mysql left outer join
Sounds like a NOT EXISTS correlated subquery is what you need:
$query = "SELECT a.UUID FROM contract a
INNER JOIN geoPoint b ON a.customer_UUID = b.customerUUID
WHERE b.garcom_UUID = '$garbCom'
AND b.city_UUID = '$city'
AND NOT EXISTS (SELECT 1
FROM contract_sales c
WHERE c.contractUUID = a.UUID)";

Extracting single data using limit with 5 tables involve

so i have 5 tables in which it is interconnected with foreign keys
and here is a sample output of table 3
what i wanted to do in table number 3 is to extract the SubdeptID of user with userid of 10 but in this case it has 2 userid10 so its print both. what i want to print is only the one with latter TransferID. my select statement is this
$sql_exp = "SELECT a.UserID, b.Employeename, c.TransferID, e.Department
FROM dbo.FA_Laptop a
INNER JOIN dbo.users b
on a.UserID = b.UserID
INNER JOIN dbo.SubDeptTransfer c
ON a.UserID = c.UserID
INNER JOIN dbo.SubDept d
ON c.SudDeptID = d.SubDeptID
INNER JOIN dbo.departments e
ON d.DeptID = e.DeptID
WHERE a.FAID = '$faidf' ORDER by c.TransferID DESC LIMIT 1";
my php code is
$rs = $conn->Execute($sql_exp);
if ($rs->EOF) {
echo "<tr><td>Please check for the Employee Name or the Department</td>";
} else {
while (!$rs->EOF){
echo "<tr><td>".$rs->Fields("Department")." / ".$rs->Fields("EmployeeName")."</td>";
$rs->movenext();
}
$rs->Close();
}
im having an error in "LIMIT" query.
MSSQL don't have LIMIT keyword.
Use TOP instead LIMIT.
$sql_exp = "SELECT TOP 1 a.UserID, b.Employeename, c.TransferID, e.Department
FROM dbo.FA_Laptop a
INNER JOIN dbo.users b
on a.UserID = b.UserID
INNER JOIN dbo.SubDeptTransfer c
ON a.UserID = c.UserID
INNER JOIN dbo.SubDept d
ON c.SudDeptID = d.SubDeptID
INNER JOIN dbo.departments e
ON d.DeptID = e.DeptID
WHERE a.FAID = '$faidf' ORDER by c.TransferID DESC";

Categories