PHP output summary based on 2 tables. - php

I have 2 tables in my database and I wanted a PHP output of the following:
Dogs 5
Cats 2
Birds 4
how can I do this?
The above is listing of categories with a count of how many dogs, cats and birds are in each category.
I have 2 tables in MySQL laid out like this:
Pets (MySql Table name)
AnimalNAME | AnimalCAT | AnimalDES
Bolt | 1 | Smelly dog
Minx | 2 | Snobby cat
Twit | 3 | Cherpy bird
Rony | 1 | Sneaky dog
Categories (MySql Table name)
AnimalCAT | Name
1 | Dogs
2 | Cats
3 | Birds

Here's the query:
SELECT
Categories.Name,
COUNT(Pets.AnimalCAT)
FROM
Categories
LEFT OUTER JOIN
Pets
ON
Categories.AnimalCAT = Pets.AnimalCAT
GROUP BY
Categories.AnimalCAT
PHP example:
mysql_connect('localhost', 'username', 'password');
mysql_select_db('dbname');
$sql = "
SELECT
Categories.Name AS `category`,
COUNT(Pets.AnimalCAT) AS `count`
FROM
Categories
LEFT OUTER JOIN
Pets
ON
Categories.AnimalCAT = Pets.AnimalCAT
GROUP BY
Categories.AnimalCAT
";
$result = mysql_query($sql) or die("Error in SQL: " . mysql_error());
while ($row = mysql_fetch_array($result)) {
echo $row['category'] . ' ' . $row['count'] . '<br />';
}

Related

Combine mysql results

I have 3 tables
Menu:
+----+--------------+
| id | name |
+----+--------------+
| 1 | Salad Salmon |
| 2 | Tomato Soup |
+----+--------------+
Cats:
+----+--------------+
| id | catname |
+----+--------------+
| 1 | Salads |
| 2 | soups |
| 3 | Fish |
+----+--------------+
Relation:
+--------+-------+
| menuid | catid |
+--------+-------+
| 1 | 1 |
| 1 | 3 |
| 2 | 2 |
+--------+-------+
$menu = "menu";
$cats = "cats";
$relation = "relation";
$sql = "
SELECT $menu.id mi, $menu.name, $cats.id, $cats.catname
FROM $menu
INNER JOIN $relation ON $menu.id = $relation.menuid
INNER JOIN $cats ON $cats = $relation.groupid
";
$result = mysqli_query($connection, $sql);
while($row = mysqli_fetch_assoc($result)){
echo '<div>'.$row[‘mi'].' '.$row['name'].' '.$row['catname'].'</div>';
}
The output shows this
1 / Salad Salmon / Salads
2 / Salad Salmon / Fish
3 / Tomato Soup / Soups
How can I combine the same ID and the output like this
1 / Salad Salmon / Salads, Fish
2 / Tomato Soup / Soups
MySQL way of doing this
SELECT menu.name, GROUP_CONCAT(catname)
FROM relation
JOIN menu ON menuid = menu.id
JOIN cats ON catid = cats.id
GROUP BY menuid
Read more about group_concat here
If you want to do it in php,
SELECT menu.id AS mid, menu.name, catname
FROM relation
JOIN menu ON menuid = menu.id
JOIN cats ON catid = cats.id
then in php
$items = [];
$result = mysqli_query($connection, $sql);
while($row = mysqli_fetch_assoc($result)){
if (!array_key_exists($row['mid'], $items) {
$items[$row['mid']] = $row['name'] . " " . $menu['catname'];
} else {
$items[$row['mid']] .= ", " . $menu['catname'];
}
}
$num = 0;
foreach ($items as $item) {
echo "<div>{++$num}. {$item}</div>";
}
You can use aggregate function GROUP_CONCAT():
SELECT
$menu.id,
$menu.name,
group_concat($cats.catname order by $cats.id separator ', ') catnames
FROM $menu
INNER JOIN $relation ON $menu.id = $relation.menuid
INNER JOIN $cats ON $cats = $relation.groupid
GROUP BY $menu.id, $menu.name

Mysql select from two tables join

i have two tables "employees" and "dependents",
Employees
|employee_No| Employee_name |
|1558 | Bean |
|1557 | Juliet |
|1556 | Zeke |
Dependents
|employee_No| dependent_name | relationship|
|1558 | Kelvin | Son |
|1558 | Mary | Daughter |
|1556 | Janet | Spouse |
is there a way i could get this data in one MySQL statement and display using php i.e. loop employees and dependent under that employee then move to the next employee.
current php code is
$employees = select_all_employees()
foreach ($employees as $covered){
echo $covered['Employee_name'].'<br/>';
$get_dependent = $select_dependent($covered["employee_No "]);
if($get_dependent != 0){
foreach($get_dependent as $details){
echo $details['dependent_name '].' '.$details['relationship'].'<br/>';
}
}
}
this takes too much time to load when there are thousand employees and dependents
expected outcome
|employee_No| dependent_name | relationship|
--------------------------------------------
|1558 | Bean | principal |
|1558 | Kelvin | Son |
|1558 | Mary | Daughter |
|1557 | Juliet | principal |
|1556 | Zeke | principal |
|1556 | Janet | Spouse |
The easiest way to get the results you want is with a UNION of the rows of the Employees table with the JOIN of the Employees with their Dependents. We do this UNION as a derived table so that we can then order the results by employee_No and also place the principal first for each employee_No. By doing it this way your PHP code becomes a simple loop over all the results.
SELECT employee_No, Employee_name AS dependent_name, 'principal' AS relationship
FROM Employees
UNION ALL
SELECT e.employee_No, d.dependent_name, d.relationship
FROM Employees e
JOIN Dependents d on d.employee_No = e.employee_No
ORDER BY employee_No DESC, relationship = 'principal' DESC
Output:
employee_No dependent_name relationship
1558 Bean principal
1558 Mary Daughter
1558 Kelvin Son
1557 Juliet principal
1556 Zeke principal
1556 Janet Spouse
Demo on dbfiddle
How about this query:
SELECT a.*, "principal" as 'relationship' FROM Employees a
UNION SELECT b.* FROM Dependents b ORDER BY employee_no DESC
DBFIDDLE here
You can use join or Map the columns. Check the index in both the tables for your slowness of query. Index should be employee_No in both the tables. And then loop your query output.
<?php
$qryOutput = array();
$query = "SELECT A.*, B.* FROM Employees A LEFT JOIN Dependents B ON A.employee_No=B.employee_No" // query
$qryOutput = execute_Query($query); // Check this syntax. For Execute query
// Loop through your Query Output
foreach ($qryOutput as $key => $value)
{ echo $value["employee_No"]." ".$value["dependent_name"]." ".$value["relationship"]; }
?>
You can use either INNER JOIN or LEFT JOIN to actualize it.
Try something like this. Though I have not tested the code.
Your table need to be created with foreign key references for it to work. see sample below. I have tested it.
create table Employees(employee_No int primary key,Employee_name varchar(100));
create table Dependents(employee_No int primary key,dependent_name varchar(100), relationship varchar(100)
foreign key (employee_No) references Employees(employee_No));
Insert for testing
insert into Employees(employee_No,Employee_name) values(1558,'Bean');
insert into Employees(employee_No,Employee_name) values(1557,'Juliet');
insert into Dependents(employee_No,dependent_name,relationship) values(1558,'kevin','son');
code
<?php
$host = "localhost"; /* Host name */
$user = "root"; /* User */
$password = ""; /* Password */
$dbname = "your-db"; /* Database name */
$con = mysqli_connect($host, $user, $password,$dbname);
// Check connection
if (!$con) {
die("Connection failed: " . mysqli_connect_error());
}
$query = 'SELECT Employees.employee_No, Employees.Employee_name, Dependents.employee_No, Dependents.dependent_name,
Dependents.relationship FROM Employees
LEFT JOIN Dependents ON Employees.employee_No = Dependents.employee_No
ORDER BY Employees.Employee_name';
$result = mysqli_query($con,$query);
while($row = mysqli_fetch_assoc($result)){
$empno = $row['employee_No'];
$empname = $row['Employee_name'];
$relation = $row['relationship'];
$dependant_name = $row['dependent_name'];
//you can now echo
echo $dependant_name.' '.$relation.'<br/>';
}
?>

How can I connect data from two different tables in mysql (LEFT JOIN)?

I want to connect data of two different tables from the mySQL database. This is working well, but I have one little problem:
$sql = "SELECT * FROM person h LEFT JOIN animals o ON ( o.name = h.name);" ;
table person:
| id | name | age |
|----|------|-----|
| 1 | fred | 9 |
| 2 | tom | 8 |
| 3 | kim | 6 |
table animals:
| id | name | animal |
|----|------|--------|
| a | fred | cat |
| b | tom | frog |
| c | kim | dog |
So for this loop...
foreach ($pdo->query($sql) as $row) {
echo "$row['id']";
echo "$row['animal']";
}
...I get the result:
| a | cat |
| b | frog |
| c | dog |
but the result I actually need is
| 1 | cat |
| 2 | frog |
| 3 | dog |
So I need the connected data from animals but still keep the id of person.
Just change the return values
"SELECT person.id id, animals.animal animal FROM person h LEFT JOIN animals o ON ( o.name = h.name);"
This will return the 2 values you want. If you need more columns just add them.
You need to get id field from person not animals.
Fetch separate id field.
$sql = "SELECT *, h.id as pid FROM person h
LEFT JOIN animals o ON o.name = h.name";
Change in PHP:
foreach ($pdo->query($sql) as $row) {
echo $row['pid'];
echo $row['animal'];
}
Use MySQL: ALIASES for table names if you are using join queries
$sql = "SELECT *, pr.id as personId FROM person pr LEFT JOIN animals al ON al.name = pr.name";
foreach ($pdo->query($sql) as $row) {
echo "$row['personId']";
echo "$row['animal']";
}
As id is ambiguous field over here and within PHP array having same key than last will overwrite the first so you need to identify those key separately like as
SELECT h.id as pid,* FROM person h
LEFT JOIN animals o ON o.name = h.name

Is this relation can be possible(phpmyadmin)

Is it possible to do this??
table1 has a column name 'id'
table2 has a column name 'id' too.
because table2 accepts multiple value from selected checkbox, and I want to relate it with table1. table1 contains the firstname lastname and etc. while table2 contains selected value from the checkbox (1 or more selected).
table1
id | firstname | lastname
1 | John | Conner
table2
id | sports
1 | basketball
2 | volleyball
3 | tennis
john selected 3 values from the checkboxes...
how can I relate or make it that the first inserted data will own the 3 values or will be displayed like this:
id | firstname | lastname | sports
1 | John | Conner | basketball
| volleyball -------->
| tennis------------->
thanks in advance...
sorry for the illustrations.
To do that, you'll need a Many to Many relationship.
You'll need a third table that keeps the relationships between the other two.
You need 3rd table that connects users to sports.
connections
--------------------------
id | users_id | sports_id
1 | 1 | 1
2 | 1 | 2
3 | 2 | 1
--------------------------
The above table would connect user #1 to sports #1 and #2, user #2 to sport #1. (I renamed the tables from your question to make my example more readable: table1 -> users and table2 -> sports)
To combine the records using this method, you can call
SELECT users.firstname, users.lastname, sports.sports
FROM connections
JOIN users ON connections.users_id = users.id
JOIN sports ON connections.sports_id = sports.id
This also ables you to show users that have selected specific sport from the list. This way you can also edit sports name once to affect all results at the same time.
Good examples of JOIN, OUTER JOIN and LEFT JOIN on w3schools
Working example using PHP/MySQLi
$db = new mysqli('localhost', 'user', 'pass', 'database'); // Database connection
if ($db->connect_errno > 0) { // Do we have a connection?
die('Unable to connect to database [' . $db->connect_error . ']');
}
// Set the sql query
$sql = "SELECT users.firstname, users.lastname, sports.sports
FROM connections
JOIN users ON connections.users_id = users.id
JOIN sports ON connections.sports_id = sports.id";
if (! ($result = $db->query($sql))) { // Run the query, get results to $result, if errors die
die('There was an error running the query [' . $db->error . ']');
}
while (($row = $result->fetch_assoc())) { // Loop through the results and echo
echo $row['firstname'] . ' ' . $row['lastname'] . ' likes ' . $row['sports'] . '<br />';
// To see all $row variables in nice format we can do: echo '<pre>' . print_r($row, true) . '</pre>';
}
I added Kyle Reese as user id #2, so the output from my query results would be:
John Conner likes basketball
John Conner likes volleyball
Kyle Reese likes basketball
Read more about MySQLi (php.net)
Example adapted from 'MySQLi for Beginners' (codular.com)

Finding users with similar specialties (numeric) as current user

I have two tables in my database
users table :
+-----------+---------------------+---------+---------+
| id | username | article | date |
+-----------+---------------------+---------+---------+
| 1 | max | 2 |392185767|
+-----------+---------------------+---------+---------+
| 2 | alex | 3 |392333337|
+-----------+---------------------+---------+---------+
user_specialtys table :
+-----------+---------------------+
| spc_id | user_id |
+-----------+---------------------+
| 1 | 1 |
+-----------+---------------------+
| 2 | 1 |
+-----------+---------------------+
| 3 | 1 |
+-----------+---------------------+
| 1 | 2 |
+-----------+---------------------+
and there is a third table with each specialty's id and name which is not important.
As you can see, each user can have many different specialties. Now in each user profile, I want to show a list of similar users (specialty wise!).
Something like:
$user_speciltys_in_array = $user->get_thisUser_specialtys();
$sql = "select `usrname` from users join user_specialtys " .
"where 'they have most similarity to $user_specialtys_in_array'";
I'm not sure how to do this.
EDIT: Oops! I didn't read the question carefully! You wanted the usernames! So we need to wrap the query above as a sub-query and use the user_ids to fine the usernames. (Modified below.)
Let's look for user ID's by counting the number of matching specialities. We'll build our SQL query using the $user_speciltys_in_array:
$user_speciltys_in_array = $user->get_thisUser_specialtys();
$sql = 'SELECT users.user_id, score, username FROM (' .
'SELECT user_id, COUNT(user_id) AS score FROM user_speciality';
$first = 1;
foreach ($user_speciltys_in_array as $spc_id)
{
$sql = $sql . (($first==1) ? ' WHERE ' : ' AND ';
$first = 0;
$sql = $sql . "(user_speciality.spc_id=$spc_id)";
}
$sql = $sql . ' GROUP BY user_id ORDER BY score DESC LIMIT 10) userscores ';
$sql = $sql . ' LEFT JOIN users ON userscores.user_id = users.user_id';
For example, if $user_speciltys_in_array is array(1,2), you'll get these results:
user_id score username
------- ----- --------
1 2 max
2 1 alex
3 1 thirdguy
I added ORDER BY score DESC and LIMIT 10 to just get the 10 best-matching users, which is often what people look for in a recommendation system (a short list of recommendations).
Try This query,
SELECT
`user_speciality`.`user_id`,
`users`.`username`,
`user_speciality`.`spc_id`
FROM
`test`.`users`
INNER JOIN `test`.`user_speciality`
ON (
`users`.`id` = `user_speciality`.`user_id`
)
ORDER BY `user_speciality`.`user_id`;

Categories