Select Distinct value for one field on Inner Join Query - php

I want to create summery report from two tables. one table project_type another ffw
Table ffw :
|-----------------------------------------------------------------------|
| ffw_id | division_id | district_id | project_type_id | name
|-----------------------------------------------------------------------|
| 1 | 30 | 1 | 2 |myAddress
|-----------------------------------------------------------------------|
| 2 | 12 | 2 | 1 | Asdfads |
|-----------------------------------------------------------------------|
| 3 | 30 | 6 | 1 | kkkkk |
|-----------------------------------------------------------------------|
| .. | .. | .. | .. | ..... |
|-----------------------------------------------------------------------|
Table project_type:
|--------------------------------
| project_type_id | project_type |
|--------------------------------|
| 1 | food |
|--------------------------------|
| 2 | work |
|--------------------------------|
| 3 | visit |
|--------------------------------|
| .. | .. |
|--------------------------------|
My desired result from that two tables after applying division_id condition will be
|-------------------------------------------|
| no | project_type | count |
|-------------------------------------------|
| 1 | food | 2 |
|-------------------------------------------|
| 2 | work | 1 |
|-------------------------------------------|
| 3 | visit | . |
|-------------------------------------------|
| .. | .. | .. |
|-------------------------------------------|
I am trying this code but it displaying duplicate value in while loop
$qry = "
SELECT * FROM `project_type`
LEFT JOIN `ffw`
ON project_type.project_type_id = ffw.project_type_id
WHERE 1
";
if (strlen($_POST["division_id"]) > 0 && $_POST["division_id"] != "0")
{
$qry .= " AND division_id = '".$_POST["division_id"]."'";
}
$query = mysql_query($qry);

You can use GROUP BY for summarize the result as like that:
SELECT pt.project_type, count(*) as count FROM project_type pt
LEFT JOIN ffw ff ON ff.project_type_id = pt.project_type_id
GROUP BY pt.project_type
This query will return you the summary of your records.
Here is the complete example of your code by using MYSQLi Object Oriented:
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT pt.project_type, count(*) as count FROM project_type pt
LEFT JOIN ffw ff ON ff.project_type_id = pt.project_type_id
WHERE 1 = 1
";
if(strlen($_POST["division_id"])> 0 && $_POST["division_id"]!="0")
{
$sql.= " AND division_id = '".$_POST["division_id"]."'";
}
$sql .= "GROUP BY pt.project_type";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
$i = 1;
// output data of each row
while($row = $result->fetch_assoc()) {
echo $id. " - Name: " . $row["project_type"]. " " . $row["count"]. "<br>";
$i++;
}
}
else
{
echo "0 results";
}
$conn->close();
Side Note: I suggest to use mysqli_* OR PDO, because mysql_* is deprecated and its not available in PHP 7

You can use group_by and get count as below :
$qry="SELECT pt.project_type_id as no, pt.project_type, count(*) as count FROM project_type pt LEFT JOIN ffw ON pt.project_type_id=ffw.project_type_id";
if(strlen($_POST["division_id"])>0&&$_POST["division_id"]!="0")
{
$qry.=" Where division_id='".$_POST["division_id"]."'";
}
$qry.=" GROUP BY pt.project_type";

Related

fetching all sub-list items under each row using foreach loop inside while loop

I have 2 tables in my product database:
product_list(id, Product_ID, Product_Name, Supplier),
product_option (id, Product_ID, Color, Size). both 'id's are primary keys with auto_increment.
I want to print all Color and Size values under each Product_Name (without repetition) that is from product_list table. I've been trying to figure out how to properly use foreach loop within while loop but now I'm out of related search result.
How my tables look:
product_list table:
|id | Product_ID | Product_Name | Supplier |
| -- | ---------- | ------------ | -------- |
| 1 |A1 | product1 | company1 |
| 2 |A2 | product2 | company2 |
| 3 |A3 | product3 | company3 |
| 4 |A4 | product4 | company4 |
product_option table:
|id |Product_ID | Color | Size |
| -- | --------- | ----- | ---- |
| 1 |A1 | red | S |
| 2 |A1 | red | M |
| 3 |A1 | black | S |
| 4 |A1 | black | M |
...
My expected output is:
| Product_ID | Product_Name | Supplier |
|:----------:|:------------:|:-----------:|
| A1 | Product1 | companyname |
| | red S | |
| | red M | |
| | black S | |
| | black M | |
| A2 | Product2 | companyname |
| | Large | |
Color and Size from product_option table with the same Product_ID will display under Product_Name row and Product_Name from product_list will only display once (instead of 4 times in the case of A1).
These are my code so far: (didn't write any table or styling for clean view)
include_once 'includes/dbh.inc.php';
$sql = "
SELECT
pl.Product_ID pid,
po.Product_ID poid,
pl.Product_Name,
po.Color color,
po.Size size,
pl.Supplier
FROM
product_list pl
LEFT JOIN
product_option po ON pl.Product_ID = po.Product_ID
ORDER BY
pl.Product_ID;";
$result = mysqli_query($conn, $sql) or die(mysqli_error());
if ($result -> num_rows > 0){
while ($row = $result -> fetch_assoc()) {
echo $row['pid'] . " " . $row['Product_Name'] . " " . $row['Supplier'] . "<br><br>";
if (!empty($row['color'] || $row['size'])) {
foreach ($row as $data) {
echo $data['color'] . ' /' . $data['size'] . '<br><br>';
}
}
}
}
Connection file: I use Xampp - phpmyadmin.
$dbServername = "localhost";
$dbUsername = "root";
$dbPassword = "";
$dbName = "product";
// Create Connection
$conn = new mysqli ($dbServername, $dbUsername, $dbPassword, $dbName);
// Check Connection
if ($conn -> connect_error) {
die("Connection Failed: " . $conn -> connect_error);
}
I'm ashamed to admit that the second 'if' and the foreach doesn't seem to work, and I don't know where to include the Product_ID match condition..
So far the output of this code is just 'A1 product1 company1', only the first result of the while loop.
From comment:
If it's ok for you to change how the data is being showed in the field, I suggest to make it horizontal with a query like this:
SELECT
pl.Product_ID pid,
po.Product_ID poid,
pl.Product_Name,
group_concat(concat(color,' ',size) separator ', ') AS Product_Name,
pl.supplier
FROM
product_list pl
LEFT JOIN
product_option po ON pl.Product_ID = po.Product_ID
GROUP BY pl.Product_ID, po.Product_ID,pl.Product_Name, pl.supplier
ORDER BY
pl.Product_ID;
Returns value like following:
+-----+------+---------------+---------------------------------+----------+
| pid | poid | Product_Name | Product_Name | supplier |
+-----+------+---------------+---------------------------------+----------+
| A1 | A1 | product1 | black M, black S, red M, red S | company1 |
.....
A fiddle of the tests
if ($result -> num_rows > 0)
mysqli_num_rows() This is a function so it is being ignored, it will always be "Zero" 0 so you will only get the indexed result which begins with '0'.. e.g [ 0,1,3]

How To Counting in Group Php MySql

How to Counting "Active People" in Table Transaction Join to Table People,
my db :
People Table
id | Name |
===========
1 | A |
2 | B |
3 | C |
4 | D |
Transaction Table
idtrx | trxone | trxtwo | idpeople |
======================================
1 | 200000 | 0 | 1
2 | 5000 | 10 | 1
3 | 0 | 200 | 4
4 | 0 | 200 | 3
im sorry i'm not good at speaking english,
I mean how to join and count active people or make transactions from the 2 tables
and make a result :
Active People
[
{
trxone: "1", //people
trxtwo: "3" //people
}
]
My code before :
<?php
require_once "conn.php";
$query = "SELECT
COUNT(DISTINCT tbl_trx.trxone) as mf
FROM tbl_people
INNER JOIN tbl_outlet ON tbl_people.id = tbl_trx.idpeople
WHERE trxone IS NOT NULL AND WHERE id = $_GET[id]";
$sql = mysqli_query ($link,$query);
$ray = array();
while ($row = mysqli_fetch_array($sql)) {
array_push($ray, array(
"totaltrxone" => $row['mf']
));
}
echo json_encode($ray);
mysqli_close($link);
?>
SELECT COUNT(DISTINCT CASE WHEN trxone THEN trxone END) trxone,
COUNT(DISTINCT CASE WHEN trxtwo THEN trxtwo END) trxtwo
FROM tbl_people

update a column so duplicated values becomes unique

Column title has a lot of duplicated values, more than once.
I need to update the column so, for example if 'gold' is duplicated - it becomes 'gold 1', 'gold 2', etc.
Something like this:
$st = $db->query("select id, title from arts order by title asc");
$st->execute();
$x = 0;
while($row = $st->fetch()){
$title = $row['title'];
//if($title.is duplicated){
$x++;
$title .= ' ' . $x;
$stb = $db->query("update arts set title = '" . $title . "' where id = " . $row['id']);
$stb->execute();
}
}
Any help?
It would be more efficient to do this in pure SQL rather than using PHP. Here is an approach that uses window functions, available in MySQL 8.0.
You can use a subquery to count how many title duplicates exists for each record, and assign a rank to each record within groups of records having the same title. Then, you can JOIN the subquery with the table to update. Where more than one record exists, you can append the row number to every record in the group.
Query:
UPDATE arts a
INNER JOIN (
SELECT
id,
title,
COUNT(*) OVER(PARTITION BY title) cnt,
ROW_NUMBER() OVER(PARTITION BY title ORDER BY id) rn
FROM arts
) b ON a.id = b.id
SET a.title = CONCAT(a.title, b.rn)
WHERE cnt > 1;
Demo on DB Fiddle
Sample data:
| id | title |
| --- | ------ |
| 10 | silver |
| 20 | gold |
| 30 | gold |
| 40 | bronze |
| 50 | gold |
| 60 | bronze |
Results after running the update query:
| id | title |
| --- | ------- |
| 10 | silver |
| 20 | gold1 |
| 30 | gold2 |
| 40 | bronze1 |
| 50 | gold3 |
| 60 | bronze2 |
Please see below code that working for me
// Create connection
$conn = new mysqli($servername, $username, $password,$dbname);
// get all row
$sql = "select id, title from arts order by title asc";
$result = $conn->query($sql);
while ($row=$result->fetch_assoc()) {
$title=$row['title'];
// select where title is same
$sql = "select * from arts where title='".$title."'";
$result2 = $conn->query($sql);
// if number of row is greater then one
if ($result2->num_rows > 1){
$x=0;
while ($row2=$result2->fetch_assoc()) {
$id=$row2['id'];
// skip first row
if($x>0){
$newTitle=$title.' '.$x;
$uquery = "update arts set title='".$newTitle."' where title='".$title."' and id=$id";
$update = $conn->query($uquery);
}
$x++;
}
}
}
and after query run
This works in MySql 5.7:
update arts a inner join (
select * from (
select t.id,
(
select count(*) + 1 from arts
where id < t.id and title = t.title
) counter
from arts t
) t
) t on t.id = a.id
set a.title = concat(a.title, ' ', t.counter)
where a.title in (
select h.title from (
select title from arts
group by title
having count(*) > 1
) h
);
See the demo.
For data:
| id | title |
| --- | -------- |
| 1 | silver |
| 2 | gold |
| 3 | diamond |
| 4 | bronze |
| 5 | gold |
| 6 | bronze |
| 7 | gold |
the result is
| id | title |
| --- | -------- |
| 1 | silver |
| 2 | gold 1 |
| 3 | diamond |
| 4 | bronze 1 |
| 5 | gold 2 |
| 6 | bronze 2 |
| 7 | gold 3 |
I think It would be more efficient to do this in SQL too, but you may can do a function to validate the duplicate, something like this:
function isDuplicated( $title, $db ){
$dp = $db->query("SELECT * FROM arts WHERE title = $title");
if ( $dp->num_rows > 1)
return true;
return false;
}
$st = $db->query("select id, title from arts order by title asc");
$st->execute();
$x = 0;
while($row = $st->fetch()){
$title = $row['title'];
if( isDuplicated( $title, $db ) ){
$x++;
$title .= ' ' . $x;
$stb = $db->query("update arts set title = '" . $title . "' where id = " . $row['id']);
$stb->execute();
}
}

Join three Tables without a common ID #MySQL

I have 3 tables cam_details, cam_category and upload_data as following..
cam_details:
+---------+-----------+-----------
| cam_id | category_id| cam_name |
+========+============+===========
| 1 | 1 | CCTV |
+--------+------------+-----------
| 2 | 1 | CCtv2 |
+--------+------------+===========
| 3 | 2 | cctv3 |
+--------+------------+===========
| 4 | 4 | cctv4 |
+--------+------------+===========
cam_category:
+-------------+---------------+
| category_id | category_name |
+=============+===============+
| 1 | Analog |
+-------------+---------------+
| 2 | Digital |
+-------------+---------------+
| 3 | Network |
+-------------+---------------+
| 4 | Simple |
+-------------+---------------+
upload_data:
+---------+-----------+
| cam_id | FILE_NAME |
+========+============+
| 1 | abc.jpg |
+--------+------------+
| 1 | abc2.jpg |
+--------+------------+
| 1 | abc3.jpg |
+--------+------------+
| 2 | xyz.jpg |
+--------+------------+
now i want to fetch the details of the cam in a array and display the results. i am able to fetch cam pic and cam_details but not the cam_category name.
code below...
<?php
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($conn,"SELECT cam_details.*, upload_data.FILE_NAME FROM `cam_details`
JOIN upload_data on cam_details.cam_id = upload_data.cam_id LEFT JOIN cam_category c
on cam_details.category_id = c.category_id
GROUP BY upload_data.cam_id ORDER BY cam_id DESC");
while($row = mysqli_fetch_array($result))
{?>
instead of left join do only join and use selec command at first for the cateroy table...
<?php
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($conn,"SELECT cam_details.*, upload_data.FILE_NAME, cam_category.* FROM `cam_details`
JOIN upload_data on cam_details.cam_id = upload_data.cam_id JOIN cam_category
on cam_details.category_id = cam_category.category_id
GROUP BY upload_data.cam_id ORDER BY cam_id DESC");
while($row = mysqli_fetch_array($result))
{?>

PHP SQL query in while loop JOIN

I'm making a basic notification system for a practice project. I have several tables, two of which look something like the following:
> Table 1: "Users"
>
userid | username | Firstname | Lastname
1 | Daffy | Daffy | Duck
2 | Flinstone | Fred | Flinstone
3 | dduck | Donald | Duck
>
> Table 2: "Notifications"
>
Notification_id | from_user_id | to_user_id | SeenOrUnseen | type
1 | 1 | 2 | 1 | fRequest
> 2 | 1 | 2 | 0 | comment
> 3 | 1 | 2 | 1 | comment
> 4 | 3 | 1 | 1 | fRequest
> 5 | 2 | 3 | 1 | fRequest
> 6 | 2 | 3 | 0 | comment
> 7 | 3 | 2 | 0 | comment
I then need data from both these tables, and would normally JOIN the tables on the user_id and from_user_id before sending of an sql query. However, a join seems to return multiple values because in the second table there are multiple instances of from_user_id. Instead, i'm querying the database, returning the data in a while loop, and within that while loop sending out another query to the database for a different tables' information:
include('../../db_login.php');
$con = mysqli_connect("$host", "$username", "$password", "$db_name");
$tbl_name = "Profile";
$tplname = "profile_template.php";
$tplname2 = "public_profile_template.php";
$myid = $_SESSION['identification'];
//CHECK CONNECTION
if(mysqli_connect_errno($con)) {
echo "failed to connect" . mysql_connect_error();
}else {
$result = mysqli_query($con, "SELECT * FROM Notifications WHERE to_user_id='$myid'");
$count = mysqli_num_rows($result);
if($count == 0){
$style = "display:none;";
} else {
echo "<ul class='notifications'>";
while($row = mysqli_fetch_array($result)){
$from_user_id = $row['from_user_id'];
$to_user_id = $row['to_user_id'];
$seen = $row['seen'];
$nature = $row['nature'];
$result2 = mysqli_query($con, "SELECT * FROM users WHERE id='$from_user_id'");
$count2 = mysqli_num_rows($result2);
if($count2 != 0){
while($row2 = mysqli_fetch_array($result2)){
$fromFirstname = $row2['Firstname'];
$fromLastname = $row2['Lastname'];
}
if($nature == 'fRequest'){
echo "<li> You have received a friend request from" . $fromFirstname . " " . $fromLastname . "</li>";
}
}
}
echo "</ul>";
}
mysqli_close($con);
}
echo "<div id='NoNotification'></div>";
echo "<div id='Notification' style='" . $style . "'></div>";
?>
Is there a better way of doing this?
Thanks for any help!
You can do something like this:
SELECT n.*, u.*
FROM Notifications n
JOIN users u ON n.from_user_id=u.id
WHERE n.to_user_id=$myid
ORDER BY n.id, u.id
You will get all the data you need. The notification data and the user data. It is better to define which fields you want to retrieve in stead of * so you got a better view of what your using and your not sending data which you don't use.
Als you are using an integer (id) as a string, you can just put the $myid there. Also beaware this is not a safe query for MySQL injection. For more info.

Categories