Search data from different tables using SQL and PHP - php

i have 4 database tables (office, facility, course, treatment) the id in office table acts as office id in all other 3 tables.
office
id name address phoneno city
1 O1 address1 12 city1
2 O2 address2 34 city2
3 O3 address2 45 city3
facility
id office_facility office_id
1 F1 1
2 F2 1
3 F3 2
Course
id office_course office_id
1 C1 1
2 C2 2
3 C3 3
Treatment
id office_treatment office_id
1 T1 1
2 T2 2
3 T3 2
i am trying to conduct a search for office on the basis of facility, course and treatment. the search code that i have worked works when there is only one table and the criteria of search is part of that same table, however this case is different.
code for search is
<?php
$con=mysqli_connect("localhost","root","","db");// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$city = mysqli_real_escape_string($con, $_POST['city']);
$sql1 = "SELECT * FROM table WHERE city LIKE '%$city%'";
$result = mysqli_query($con, $sql1);
if (mysqli_num_rows($result) > 0)
{
while($row = mysqli_fetch_assoc($result)) {
echo "Office name: " . $row["office_name"]. " - Location: " . $row["office_address"]. " " . $row["office_city"]. "<br>";
}
} else {
echo "0 results";
}
mysqli_close($con);
?>
Would appreciate if anyone could tell me how i can search offices from these tables

You might want to perform a complex SQL query against database, concatenating all the conditions you have:
SELECT address FROM office
JOIN facility ON (facility.office_id = office.id)
JOIN course ON (course.office_id = office.id)
JOIN treatment ON (treatment.office_id = office.id)
WHERE city LIKE %...%
AND office_facility LIKE %...%
AND office_course LIKE %...%
AND office_treatment LIKE %...%
The values for LIKE as well as boolean logic on AND/OR is now up to you.

You can use union for that
select A.ID,(SELECT B.Name from office B where A.ID=B.ID) as Name from (
select id from office where <Your Office Table filter Criteria>
UNION
select office_id from facility where <Your facility Table filter Criteria>
UNION
select office_id from Course where <Your Course Table filter Criteria>
UNION
select office_id from Treatment where <Your Treatment Table filter Criteria>
)A

You can use join query. Actually you haven't clarify that what is you need so I ma trying to give you same basic(global) example
"select from table_name as td
left join anoather_table as anoth on td.common_column = anoth.commoncolun whare td.condition_columh= condition"

Related

How to displays total count of instructors for each department ? SQL Query

Here is the department table
department_id | department_name
1 computers
2 maths
3 physics
4 mba
Here is instructor table
instructor_id | department_id | name
1 1 abc
2 2 manu
3 2 raju
4 3 jaya
5 4 man
From above code how to displays total count of instructors for each department?
what will be the query?
Please help.
I'm doing it in codeigniter.
select d.department_id, count(*) as num_instructors
from departments d
inner join instructors i on i.department_id = d.department_id
group by d.department_id;
You may try to conceptualize from my solution below and see if it can help,
To avoid complication you could just go direct
<?php
//connection
$link = mysqli_connect("localhost","root","","database_name") or die("Couldn't make connection.");
$computer_department_id = //the value
$query = mysqli_query($link, "SELECT department_id FROM instructure_table WHERE department_id='$computer_department_id')");
$total = mysqli_num_rows($query);
echo $total; //this one will display the total number of instructors in computer department
?>
Or if you like
<?php
//connection
$link = mysqli_connect("localhost","root","","database_name") or die("Couldn't make connection.");
$computer_department = //the value
$query = mysqli_query($link, "SELECT department_id
FROM instructure_table AS t
WHERE EXISTS (SELECT department_id
FROM department_table AS d
WHERE d.department_id = t.department_id AND department_id='$computer_department')");
$total = mysqli_num_rows($query);
echo $total; //this one will display the total number of instructors in computer department
?>
So if you place the query in the department line s
department_id | department_name
1 computers //the query
2 maths //the query
3 physics //the query
4 mba //the query
Even if the query for department is in a repeating region it would still work for you. regards
SELECT COUNT(i.instructor_id) as `instructor_count`, d.department_name
FROM instructor AS i
JOIN department ON d.department_id = i.department_id
GROUP BY i.department_id"

Inner Join MYSQL Query Combining 3 tables

How can I combine 3 tables in a INNER JOIN?
The end result I am after is getting a list of CATEGORIES belonging to a PRODUCT - including the CATEGORY'S PARENT ID CATEGORY value (ie: Sneakers and Nike).
The CATEGORIES table and PRODUCTS table are joined in the PRODUCTS & CATEGORIES table. A product can belong to many categories and a category can have many products.
Here's more-or-less the setup I have in my database...
CATEGORIES TABLE:
CAT ID | PARENT ID | CATEGORY
1 | 0 | Sneakers
2 | 1 | Nike
3 | 2 | Jordan
PRODUCTS TABLE:
PROD ID
1
2
3
PRODUCTS & CATEGORIES TABLE:
CAT ID | PROD ID
1 | 0
1 | 1
2 | 3
I am running these queries and I am getting some results, but at the moment I am running 2 separate queries...
$q1 = "SELECT prodid, GROUP_CONCAT(catid SEPARATOR ' // ') as catid FROM products_categories group by prodid order by prodid";
$result1 = $conn->query($q1);
if ($result1->num_rows > 0) {
while($prods = $result1->fetch_assoc()) {
echo "Product Id:" . $prods["prodid"] . " ––> " . "Categories Id:" . $prods["catid"];
}
} else {
echo "0 results";
}
$q2 =
" SELECT `ID`.`category` as `IDName`, `LABEL`.`category` as `LabelName`, `LABEL`.`catid` as `LabelId`
FROM `categories` as ID
INNER JOIN `categories` as LABEL
ON `ID`.`catid` = `LABEL`.`parentid`";
$result2 = $conn->query($q2);
if ($result2->num_rows > 0) {
while($prods = $result2->fetch_assoc()) {
echo "ID# " . $prods["LabelId"] . " is called: ". $prods["LabelName"] . "<br>";
}
} else {
echo "0 results";
}
$conn->close();
I have tried adding another INNER JOIN with no luck in the results.
The end result I am after would be: PROD ID #0 belongs to Sneakers, Nike, Jordan.
Anyone can point me in the right direction?
Thank you so much,
Sergio
UPDATE - 10/11/16
The Query:
$q =
" SELECT PC.productid as productid, concat_WS('~',C1.category, C2.category, C3.category) as breadcrumb
FROM xcart_categories as C1
INNER JOIN xcart_products_categories as PC
ON C1.categoryid = PC.categoryid
LEFT JOIN xcart_categories as C2
ON C1.categoryid = C2.parentid
AND C1.parentid = 0
LEFT JOIN xcart_categories as C3
ON C2.categoryid = C3.parentid
WHERE C1.parentid = 0
";
The Fetch:
$result = $conn->query($q);
if ($result->num_rows > 0) {
while($prods = $result->fetch_assoc()) {
echo $prods['productid'] . ' Belongs in these categories: ' . $prods['breadcrumb'] . '<br>';
}
} else {
echo "0 results";
}
This assumes 3 levels of hierarchy no more and a separate join is needed to "put each record on the same line" so they can be combined into a single value result. I thin you were trying to use Group_concat but I can't see how that's going to work as you don't have a way to walk the hierarchy.
SELECT PC.ProductID, concat_WS('-',C1.Category, C2.Category, C3.Category) as breadcrumb
FROM categories C1
INNER JOIN ProductsCategories PC
on C1.categoryID = PC.CategoryID
LEFT JOIN categories C2
on c1.CategoryID = C2.ParentID
and C1.parentID = 0
LEFT Join Categories C3
on C2.CategoryID = C3.ParentID
WHERE C1.ParentID = 0
Working SQL Fiddle example ( this only supports 3 levels deep, but could be altered with added left joins to support a max level but not a undetermined max level..)
I see you're trying to use group concat to bring all the rows for the same product category.productID of 0 to the same line
However as 0 references catID of 1 it would only return "sneakers" on the inner join. You would need to traverse the tree (all of it) somehow, thus the above, or you have to take multiple trips to the db or use some sort of dynamic SQL or method mentioned in link in comments.
This would be fairly simple in SQL Server, Oracle or other Enterprise RDBMS systems, however without recursive queries or engine specific hierarchy queries, this is no easy feat in MySQL on a single trip.
Maybe I'm missing something so it may help to see the actual expected results for your sample data. What is the record set look like that you want back?

sql join repeating results

I need to make a list printing all the clients ordered by the gym name, but it's repeating the gym name the same number of gym's clients. If gym1 have 4 clients, the echo is printed 4 times.
The tables/columns are:
members (id, gym, name, etc...)
and
gym (gymID, gym_name, etc...).
member.gym is to know to what gym the client belongs (gym.gymID)
if ($stmt = $mysqli->prepare(" SELECT DISTINCT g.*, m.*
FROM gym g
INNER JOIN members m ON m.gym = g.gymID")) {
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_array()) {
echo 'Sport center: ' . $row['gym_name'] . '<br>';
// here print the gym's clients list
}
}
DISTINCT is not working... What is the problem??
That's the normal behavior.
Example.
Consider the following tables
Table "gym"
-----------
gym_id | gym_name
-------+----------
1 | Gym A
2 | Gym B
Table "members"
---------------
member_id | gym_id | member_name
----------+--------+------------
1 | 1 | Bob
2 | 1 | Jeff
And now, execute this query:
select g.gym_id, g.gim_name, m.member_id, m.member_name
from gym as g
inner join members as m on g.gym_id = m.gym_id;
Result:
gym_id | gym_name | member_id | member_name
-------+----------+-----------+-------------
1 | Gym A | 1 | Bob
1 | Gym B | 2 | Jeff
That happens because each row in the gym table is matched with a row in the members name. Even if you use select distinct, the result would be the same, because every row is different.
I think what you want is an output like this:
Gym A
Bob
Jeff
Although that can be done directly in SQL, it's easier to handle it directly with PHP, because doing it in SQL would be a real pain in the neck would require writing quite a complex query. I'm not quite good with PHP, but it could be something like this:
/*
You don't need "DISTINCT", but you need "ORDER BY" to make this work
*/
if ($stmt = $mysqli->prepare(" SELECT g.*, m.*
FROM gym g
INNER JOIN members m ON m.gym = g.gymID
ORDER BY g.gymID")) {
$stmt->execute();
$result = $stmt->get_result();
$gym = "";
while ($row = $result->fetch_array()) {
if($row['gym_name'] != $gym)
echo 'Sport center: ' . $row['gym_name'] . '<br>';
echo ' Member: ' . $row['member_name'] . '<br>';
$gym = $row['gym_name'];
}
}
First, drop the DISTINCT and slap in an ORDER BY:
SELECT g.*, m.*
FROM gym g
INNER JOIN members m ON m.gym = g.gymID
ORDER BY g.name;
Now, adjust your PHP code to only print the gym name if it's different from the last gym you printed.
SELECT g.*, m.*
FROM gym g
INNER JOIN members m ON m.gym = g.gymID
ORDER BY g.name,gym_clients;
I dont know the name of Gym Name column & gym Client Column So, Please Change the name if they are not correctly spelled.
I hope this will work for you
This should work:
SELECT *
FROM gym g
LEFT JOIN members m
ON g.gym_ID=m.gym_id
GROUP BY g.gym_name

Use commaseparated mySQL column value in LIKE

I have column in my database named as foodtype . Table name is restaurant and the column foodtype has comma separated values (as Indian,Chinese).
Now, when a person select Chinese then the i want mysql query should return restaurant where foodtype is Chinese.
Query should become like as below:
SELECT * FROM restaurant WHERE cityname='Chicago' and foodtype
LIKE ('%Chinese%')
And when a person select Indian then the i want mysql query should return restaurant where foodtype is Indian.
Query should become like as below:
SELECT * FROM restaurant WHERE cityname='Chicago' and foodtype
LIKE ('%Indian%')
And when a person select Indian and Chinese both then the i want mysql query should return restaurant where foodtype is Indian and Chinese.
Query should become like as below:
SELECT * FROM restaurant WHERE cityname='Chicago' and foodtype
LIKE ('%Indian%,%Chinese%')
Please let me know how can i achieve this.
Use FIND_IN_SET()
SELECT *
FROM restaurant
WHERE cityname='Chicago'
and find_in_set(foodtype, 'Indian') > 0
and find_in_set(foodtype, 'Chinese') > 0
But actually you are better off by chaning your table structure. Never, never, never store multiple values in one column!
To achieve that you can add 2 other tables to your DB
foodtypes table
---------------
id
name
restaurant_foodtypes
--------------------
restaurant_id
foodtype_id
Example data:
foodtypes
id | name
1 | chinese
2 | indian
restaurant_foodtypes
restanrant_id | foodtype_id
1 | 1
1 | 2
Then you can select restaurants having both foodtypes like this
select r.name
from restaurants r
join restaurant_foodtypes rf on rf.restaurant_id = r.id
join foodtypes f on rf.foodtype_id = f.id
where f.name in ('indian','chinese')
group by r.name
having count(distinct f.name) = 2

How to separate data extracted from the table in PHP

I extracted data from a database and sorted it based on the id. Now i need to separate out the rows with different ids. The aim is to find out the total price for each id and the latest date.
b_id price date
---- ----------------
1 98.30 2014-05-14
1 65.70 2014-05-07
2 14.40 2014-05-06
2 55.60 2014-05-07
2 38.20 2014-04-06
3 84.40 2014-04-02
3 31.30 2014-04-12
3 74.40 2014-05-06
I tried to separate it using -
while ($row = mysqli_fetch_array($result1)) {
if($row['b_id'] == 1){
}
}
But i cannot hard code it. How can i separate out the rows? Am i doing it wrong?
You can do what you want rigth on your query. It would be like:
select b_id, max(date) as maxdate, sum(price) total
from your table
group by b_id
order by b_id
If you want the total price, your extraction could be
SELECT b_id, SUM( price) AS total_price FROM your_table GROUP BY b_id
while ($row = mysqli_fetch_array($result1)) {
echo "Id : " . $row['b_id'] . " Price : " . $row['total_price'];
}
You should use SQL to achieve your goal. It's usually faster when the database handles simple calculations:
SELECT b_id,
SUM(price) AS 'Price',
MAX(date) AS 'Date'
FROM YourTable
GROUP BY b_id

Categories