Search through multiple tables mysql - php

I have a table Product and Classification and a join table Product_Classification. I wrote a query to search through the tables. One thing I notice is that If I have a product record (or Classification) that is not mapped to Classification the query will not return anything. How can I change my query in a such a way that it does ALSO return a Product that is not mapped a Classification (and a Classification data that is not mapped to a product).
$query = "Select * from $dbname.Product P INNER JOIN Product_Classification PC ON P.ProductID = PC.ProductID INNER JOIN Classification C ON PC.ClassificationID = C.ClassificationID ";
EDIT: I do have a Where condition, which is an array of fields

You can use this query
$query = "Select * from $dbname.Product P LEFT JOIN Product_Classification PC ON P.ProductID = PC.ProductID LEFT JOIN Classification C ON PC.ClassificationID = C.ClassificationID ";
If you want to see more about joins, this link will help you https://stackoverflow.com/a/4715847/6098214

use this query
Select * from $dbname.Product P INNER JOIN Product_Classification PC ON P.ProductID = PC.ProductID LEFT JOIN Classification C ON PC.ClassificationID = C.ClassificationID

Related

More than 2 OR conditions in PHP search

I'm very new to PHP and SQL. I'm trying to display search results from my MySQL database via a search box and the SELECT statement I'm using to clarify what results should be displayed will only accept two OR conidtions, and after that won't let me add any more. It just turns gray in Atom and doesn't do anything when I try to search by that condition in the interface. Here is what it looks like in Atom, and the code: SELECT statement
$sql = "SELECT * FROM Clients AS c
INNER JOIN Rentals AS r ON c.Client_ID = r.Client_ID
INNER JOIN Cases AS ca ON r.Client_ID = ca.Case_ID
INNER JOIN Judgments AS j ON ca.Case_ID = j.Case_ID
INNER JOIN Lockouts AS l ON j.Judgment_ID = l.Judgment_ID
WHERE First_name = '$search' OR Last_name = '$search'
OR Phone_number = '$search' OR Email_address = '$search';";
I'm wondering how I can add more OR conditions to the SELECT statement, or if there's some other way I should be approaching this. Thank you!
$sql = "SELECT * FROM Clients AS c
INNER JOIN Rentals AS r ON c.Client_ID = r.Client_ID
INNER JOIN Cases AS ca ON r.Client_ID = ca.Case_ID
INNER JOIN Judgments AS j ON ca.Case_ID = j.Case_ID
INNER JOIN Lockouts AS l ON j.Judgment_ID = l.Judgment_ID
WHERE c.First_name = '$search' OR c.Last_name = '$search'
OR c.Phone_number = '$search' OR c.Email_address = '$search';";
I am assuming that First_name, Last_name etc column is in Clients table that is why i have used c.First_name and so on. As you have aliased Clients table as c.
Note INNER JOIN clause join table if when ON condition meet and get result.
You can use LEFT JOIN clause to get LEFT TABLE (Clients ) event if Join condition not meet.

Joining 3 Tables from MySQL, and searching join based on user input

I need to join 3 tables and be able to search that join from user input.
The tables are
ufoTable, cryptobiologyTable, and unexplainedTable
I need to join those and allow the user to search it based on year, and/or location.
I tried
$sql = "SELECT * FROM ufoTable
LEFT JOIN cryptobiologyTable
ON cryptobiologyTable.firstYear = ufoTable.year
LEFT JOIN unexplainedTable
ON unexplainedTable.year = ufoTable.year";
But im not sure if its working or how id search that join with the input
For output I need the page to display results based on the users query of the joined tables
select *
from ufoTable a, cryptobiologyTable b, unexplainedTable c
where b.firstYear = a.year and c.year = a.year
OR
SELECT *
FROM ufoTable a
INNER JOIN cryptobiologyTable b ON a.year = b.firstYear
INNER JOIN unexplainedTable c ON a.year = c.year
ORDER BY a.year

How I can merge repeated rows in MySQL?

I'm working on a project that each orgnizations have barriers, each organization can contain 1 or more barriers, and then I need generate an XML file that show each barrier into the organization .
But executing this sql code:
SELECT organizations.*, barriers.barrierName AS bname, barriers.type AS btype, geographs.name AS geo, rpd.rpdname AS rpdn, rpd.meaning AS rpdmean FROM organizations
left join orgbarriers on orgbarriers.idOrg = organizations.id
left join barriers on orgbarriers.idBarrier = barriers.id
left join orggeographs on organizations.id = orggeographs.idOrg
left join geographs on geographs.id = orggeographs.idGeo
left join orgrpds on orgrpds.idOrg = organizations.id
left join rpd on rpd.id = orgrpds.idRPD
I get repeated rows like this image:
Use the keyword "DISTINCT"
SELECT DISTINCT rest of your query

PHP SQL how the get the exact count from a table

I have two tables with the following columns:
FAMILY - id, ...
PRODUCTS - id, idfamily, type, ...
FAMILY & PRODUCTS are connected with family.id = products.idfamily.
I'm doing pagination over families with filters based on products types, so I'm trying to get the exact count of FAMILY containing almost one product with a specific type.
First query is ok, I get all the families:
if (!isset($_GET['type']) || $_GET['type'] == 'all') {
$query_family=mysql_query("SELECT * FROM family");
}
$count=mysql_num_rows($query_family);
// result = 166
Unfortunately, the following query is wrong:
} else {
$query_family=mysql_query("
SELECT * FROM family f LEFT JOIN products p ON f.id = p.idfamily
WHERE p.type = '$_GET[type]'
");
}
$count=mysql_num_rows($query_family);
// result = 500+
it's wrong because I get all the products with a type, but I'm trying to get the number of families containing products with the selected type ($_GET[type]).
Thank you
You should have
SELECT distinct f.id from family f LEFT JOIN products p on f.id = p.idfamily WHERE p.type = '$_GET[type]' in the second query
I think.
SELECT COUNT(*) as nbr FROM family
INNER JOIN products ON products.idfamily = family.id
WHERE product.type = ".intval($_GET['type'])."
GROUP BY family.id
Avoid the mysql_ driver, use PDO or mysqli instead. Don't forget to protect you from sql injections too.
To get the count of families with a specified type, use
SELECT * FROM family f INNER JOIN products p ON f.id = p.idfamily
WHERE IFNULL(p.type, 'notspecified') = '$_GET[type]'
With INNER JOIN instead of LFET JOIN you get only rows where a connection between f.id and p.idfamily exist. By LEFT JOIN, all family rows are returned with NULL values in the fields of product table.
So when p.type is NULL, your p.type = '$_GET[type]' evaluates always to NULL, and your filtering will not work as expected. For this reason, use IFNULL.
You can try below code:
$query_family=mysql_query("
SELECT COUNT(f.id) AS cnt FROM family f
INNER JOIN products p ON f.id = p.idfamily
WHERE p.type = '$_GET[type]'");
Also try to use mysqli not mysql.
And you don't have to use mysql_num_rows, you can get the right number directly from mysql:
$query = "SELECT COUNT(DISTINCT f.id) ".
"FROM family f ".
"LEFT JOIN products p ON f.id = p.idfamily ".
"WHERE p.type = '".$_GET['type']."'";
Use INNER JOIN instead of LEFT.

mysql join return 0 for one column with other columns intact

I wish to join multiple tables like- Categories, menus, restaurants, reviews, etc.
to return the restaurants that provide the inserted food with their prices.
Everything works except numberOfReviews in reviews table.
If a restaurant has no reviews then output should be 0 for numOfReviews column but other column values should be retrieved i.e. price, name, etc.
With following query I get all fields as null and count(numReviews) as 0:
select r.id
,r.`Name`
,r.`Address`
,r.city
,r.`Rating`
,r.`Latitude`
,a.`AreaName`
,m.`Price`
,count(rv.id)
from `categories` c, `menus` m, `restaurants` r, areas a, reviews rv
where m.`ItemName`="tiramisu"
and c.`restaurant_id`=r.`id`
and m.`category_id`=c.id
and r.`AreaId`=a.`AreaId`
and if I can't match rv.restaurant_id=r.id in where clause(obviously).
Where am I getting wrong? How do I solve this?
edited
select r.id,
r.`Name`,
r.`Address`,
r.city,
r.`Rating`,
r.`Latitude`,
a.`AreaName`,
m.`Price`,
r.`Longitude`,
r.Veg_NonVeg,
count(rv.id)
from restaurants r LEFT JOIN `reviews` rv on rv.`restaurant_id`=r.`id`
inner join `categories` c on c.`restaurant_id` = r.id
inner join `menus` m on m.`category_id` = c.id
inner join `areas` a on a.`AreaId` = r.`AreaId`
where m.`ItemName`="tiramisu"
First of all, don't use this old school syntax for the jointures.
Here is a query that may solve your problem:
SELECT R.id
,R.Name
,R.Address
,R.city
,R.Rating
,R.Latitude
,R.Longitude
,A.AreaName
,M.Price
,R.Veg_NonVeg
,COUNT(RV.id) AS numOfReviews
FROM restaurants R
INNER JOIN categories C ON C.restaurant_id = R.id
INNER JOIN menus M ON M.category_id = C.id
INNER JOIN areas A ON A.AreaId = R.AreaId
LEFT JOIN reviews RV ON RV.restaurant_id = R.id
WHERE M.ItemName = 'tiramisu'
GROUP BY R.id, R.Name, R.Address, R.city, R.Rating, R.Latitude, R.Longitude, A.AreaName, M.Price, R.Veg_NonVeg
I used explicit INNER JOIN syntax instead of your old school syntax and I modified the jointure with table reviews in order to get the expected result. The GROUP BY clause is required to use the aggregate function COUNT, every rows will be grouped by the enumerated columns (every column except the one used by the function).
Here is another solution that simplify the GROUP BY clause and allow the modification of SELECT statement without having to worry about the fact that every columns need to be part of the GROUP BY clause:
SELECT R.id
,R.Name
,R.Address
,R.city
,R.Rating
,R.Latitude
,R.Longitude
,A.AreaName
,M.Price
,R.Veg_NonVeg
,NR.numOfReviews
FROM restaurants R
INNER JOIN (SELECT R2.id
,COUNT(RV.id) AS numOfReviews
FROM restaurants R2
LEFT OUTER JOIN reviews RV ON RV.restaurant_id = R2.id
GROUP BY R2.id) NR ON NR.id = R.id
INNER JOIN categories C ON C.restaurant_id = R.id
INNER JOIN menus M ON M.category_id = C.id
INNER JOIN areas A ON A.AreaId = R.AreaId
WHERE M.ItemName = 'tiramisu'
As you can see here I added a new jointure on a simple subquery that does the aggregation job in order to provide me the expected number of reviews for each restaurant.
Hope this will help you.

Categories