PHP using PDO with two data tables - php

I want the status column to show the value "free" when there is no corresponding record in the device_transactions table, or there is a corresponding record in the device_transactions table with the returned_date blank field
My desired return result is like this
That's all I can do right now
How can I print row #4 while the device_transactions table has no corresponding records in the devices table?
The 2 data tables
Table devices:
id
name
1
Laptop01
2
Laptop02
3
Laptop03
4
Laptop04
Table device_transactions:
id
device_id
start_transaction_plan
end_transaction_plan
returned_date
1
1
2021-12-10 14:20:43
2021-12-12 07:00:00
2021-12-12 9:30:23
2
2
2021-12-11 10:10:20
2021-12-15 15:30:00
2021-12-16 7:30:45
3
3
2021-12-12 19:03:00
2021-12-21 08:00:00
NULL
<table id="myTable">
<thead>
<tr>
<th>No</th>
<th>Name</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<?php
$sql = $conn->prepare("SELECT devices.id, devices.name, device_transactions.returned_date
FROM devices, device_transactions WHERE devices.id = device_transactions.device_id ");
$sql->execute();
$result = $sql->setFetchMode(PDO::FETCH_ASSOC);
foreach ($sql->fetchAll() as $row) { ?>
<tr>
<td><?php echo $row['id']; ?></td>
<td><?php echo $row['name']; ?></td>
<td><?php
if($row['returned_date'] !== null ){
echo "free";
}
else{
echo "borrowed";
}
?></td>
</tr>
<?php }
?>
</tbody>
</table>

You want to use LEFT JOIN, instead of FROM devices, device_transactions (which is an INNER JOIN).
SELECT devices.id, devices.name, device_transactions.returned_date
FROM devices
LEFT JOIN device_transactions ON devices.id = device_transactions.device_id

Just use a simple LEFT JOIN and you'll get all the record:
OK I've made a little edit so my answer is not the same as already givven and this will help you to avoid checkinh if return date is null or not
SELECT d.id as deviceid, d.name as devicename, c.returned_date as returndate
FROM device d
LEFT JOIN device_transactions c ON c.device_id = d.id;
Edit of the query - so now if there is no record or return date is null you'll get 'free' as returntype else you get 'borrowed'(you can put whatever you want of course...) So now no need in php to check if $row['return_date'] == null just output the result from the query:
SELECT d.id as deviceid, d.name as devicename,
CASE WHEN c.returned_date IS NULL THEN 'free' ELSE 'borrowed' END as returntype
FROM device d
LEFT JOIN device_transactions c ON c.device_id = d.id;
See it working here
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=32db15fbb2b00d780196ea879e6f7d20
Edited result:
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=4edc860aa39461f2c5e6655bbca77d66

Related

fast way to Join and filter data from multiple tables on mysql

Hi first i'm sorry for my bad english...I develop a php application to input merchant visit result for my office.
Here the structure of my mysql database :
Table merchant :
id, name, address, phone, area
Table device :
id, merchid, tid, sn, status
Table visit :
id, date, time, merchid, deviceid, act, result
the relation for that 3 tables is below :
device.merchid -> merchant.id
visit.merchid -> merchant.id
visit.deviceid -> device.id
what i want is join that 3 tables as view that contain bellow field :
View joindevice :
devid, merchid, merchname, merchaddr, merchph, mercharea, devtid, devsn,
devstat, lastact, lastvisit, lastresult
where lastact, lastresult and lastvisit use data from 'visit' table for each device.
what i have done now is create mysql view using bellow query :
select
device.id AS devid,
device.merchid AS merchid,
merchant.name AS merchname,
merchant.address AS merchaddr,
merchant.phone AS merchph,
merchant.area AS mercharea,
device.tid AS devtid,
device.sn AS devsn,
device.status AS devstat,
ifnull(
(
select visit.act from visit
where visit.devid = device.id
order by visit.date desc limit 1
),''
)AS lastact,
ifnull(
(
select visit.date from visit
where (visit.devid=device.id)
order by visit.date desc limit 1
),''
)AS lastvisit,
ifnull(
(
select visit.result from visit
where (visit.devid=device.id)
order by visit.date desc limit1
),''
)AS lastresult
from (device join merchant) where (merchant.id=device.merchid)
here the php script to call that JoinDevice View :
<?php
$sql = "SELECT * FROM joindevice order by merchname asc";
$qry=mysql_query($sql);
$check=mysql_num_rows($qry);
if($check>0){
?>
<table>
<thead>
<tr>
<th>No.</th>
<th>TID</th>
<th>SN</th>
<th>Phone</th>
<th>Merchant Name</th>
<th>Merchant Address</th>
<th>Merchant Area</th>
<th>Device Status</th>
<th>Last Visit</th>
<th>Last Act</th>
<th>Last Result</th>
</tr>
</thead>
<tbody>
<?php
$no=1;
while($dt=mysql_fetch_assoc($qry)){
?>
<tr>
<td><?php echo $no; ?></td>
<td><?php echo empty($dt['tid'])?'-':$dt['tid']; ?></td>
<td><?php echo empty($dt['sn'])?'-':$dt['sn']; ?></td>
<td><?php echo empty($dt['merchph'])?'-':$dt['merchph']; ?></td>
<td><?php echo empty($dt['merchname'])?'-':$dt['merchname']; ?></td>
<td><?php echo empty($dt['merchaddr'])?'-':$dt['merchaddr']; ?></td>
<td><?php echo empty($dt['mercharea'])?'-':$dt['mercharea']; ?></td>
<td><?php echo empty($dt['devstat'])?'-':$dt['devstat']; ?></td>
<td><?php echo empty($dt['lastvisit'])?'-':$dt['lastvisit']; ?></td>
<td><?php echo empty($dt['lastact'])?'-':$dt['lastact']; ?></td>
<td><?php echo empty($dt['lastresult'])?'-':$dt['lastresult']; ?></td>
</tr>
<?php
$no++;
}
?>
</tbody>
</table>
<?php
}
?>
everything work fine when the data in 'device' table is small but now the data is about 1700 item so time to execute that php script is too long, sometime when i execute that php script the result is gateway timeout, but when i execute php script that only get data from one table it open fast...can anyone help me how to reduce that execute time?what should i do?
You could try eliminating those correlated subqueries and replacing them with formal joins:
SELECT
t1.id AS devid,
t1.merchid AS merchid,
t1.tid AS devtid,
t1.sn AS devsn,
t1.status AS devstat,
t2.act AS lastact,
t2.date AS lastvisit,
t2.result AS lastresult,
t3.name AS merchname,
t3.address AS merchaddr,
t3.phone AS merchph,
t3.area AS mercharea,
FROM device t1
INNER JOIN
(
SELECT t1.*
FROM visit t1
INNER JOIN
(
SELECT devid, MAX(date) AS date
FROM visit
GROUP BY devid
) t2
ON t1.devid = t2.devid AND
t1.date = t2.date
) t2
ON t1.id = t2.devid
INNER JOIN merchant t3
t1.merchid = t3.id
Whether an index would prove beneficial to the above would depend on a number of things, but in any case I expect improvement over your original query.

Displaying Data From 4 (Four) Tables in Mysql

I just need a simple queries actually,
Here are my tables:
Information -> id_info, year, information_name, person_name, country_id, state_id, city_id
Country -> id, country_id, country_name
State -> id, state_id, country_id, state_name
City -> id, city_id, state_id, city_name
I have runs some queries, for example's:
SELECT *
FROM information, country, state, city
WHERE information.country_id =country.country_id
AND information.state_id = state.state_id
AND information.city_id = city.city_id
GROUP BY information.id_info;
My Simple Scripts:
echo '<td>'.$data['country_name'].'</td>
echo '<td>'.$data['state_name'].'</td>
echo '<td>'.$data['city_name'].'</td>
$data-> Is my while script with $query=mysql_query...
from the queries above only displaying two (2) data's from my database, but in the database it has five (5) data's.
Then I've trying to delete the Group statement, but the data kept looped and displaying almost 8000 data's, but I only got 5 data on tables.
I've tried everything, left join, right join, inner join....
I need help, I know it's quite simple, but how can I just display all the data normally.
Thanks.
Here My Full Scripts for displaying the data:
<table cellpadding="5" cellspacing="0" border="1">
<tr bgcolor="#CCCCCC">
<th>No.</th>
<th>Year</th>
<th>Information Name</th>
<th>Person Name</th>
<th>Country</th>
<th>State</th>
<th>City</th>
<th>Act</th>
</tr>
<?php
include('connect.php');
$query = mysql_query("SELECT *
FROM information
INNER JOIN country ON information.country_id =country.country_id
INNER JOIN state ON information.state_id = state.state_id
INNER JOIN city ON information.city_id = city.city_id
GROUP BY information.country_id, information.state_id, information.city_id") or die(mysql_error());
if(mysql_num_rows($query) == 0){
echo '<tr><td colspan="6">No data!</td></tr>';
}else{
$no = 1;
while($data = mysql_fetch_assoc($query)){
echo '<tr>';
echo '<td>'.$no.'</td>';
echo '<td>'.$data['year'].'</td>';
echo '<td>'.$data['information_name'].'</td>';
echo '<td>'.$data['person_name'].'</td>';
echo '<td>'.$data['country_name'].'</td>';
echo '<td>'.$data['state_name'].'</td>';
echo '<td>'.$data['city_name'].'</td>';
echo '<td>Detail / Edit / Delete</td>';
echo '</tr>';
$no++;
}
}
?>
You can use INNER JOIN assuming that index key is properly used:
SELECT country.country_name,
state.state_name,
city.city_name
FROM information
INNER JOIN country ON information.country_id = country.country_id
INNER JOIN state ON information.state_id = state.state_id
INNER JOIN city ON information.city_id = city.city_id
Try changing your GROUP BY and use INNER JOIN :
SELECT *
FROM information
INNER JOIN country ON information.country_id =country.country_id
INNER JOIN state ON information.state_id = state.state_id
INNER JOIN city ON information.city_id = city.city_id
GROUP BY information.country_id, information.state_id, information.city_id
It worked now, *sigh the problem is the table in information, I have to empty the table first.
It quite a lot happened to me, the records was the problem source's, I've been through this a lot. Thank you guys for the help, now it's work perfectly fine.
The two answer above worked perfectly, Thank you.

Values inserted through MySQLi could not be fully inserted with mysqli_insert_id

Good Day, this is just a follow-up question from Referrence 1 here on stackoverflow. Though it was now being solved partially, I still have issues with eid. The multiple insert through mysqli is a bit working (I just said a bit since only 4 our of 6 tables were being inserted with values), but when I checked if the foreign key for eid are also been copied by mysqli_insert_id() I'm surprised to see that the foreign key eid got 0 values.
It was like this (NOTE: The ff: data are not the actual one):
Table: Employee [eid is it's primary key]
eid employee_name address etc
1002 employee A Beside U ♥
1003 employee B Pluto ♥
Table: Contact [eid is it's foreign key]
eid telno email
0 911 kingCorbra#hey.com
0 *** universe#hey.com
Table: Work Experience [eid is it's foreign key]
eid Company Name start date end date
0 Windows Macintosh 2012-12-01 2012-12-02
0 Micro Entertainment LG 2012-12-31 2013-01-01
*Other Tables are not included in the samples but part of the query.*
As you know, I have used mysqli_insert_id() during the insert statement again please see the Referrence 1, and luckily it work but only for 4 out of 6 actual tables. And when I checked the eid column it shows 0 values.
Here is my select statement (not the real one):
` <table cellspacing="0" width="100%">
<thead>
<tr>
<th><strong>Name:</strong></th>
<th><strong>Date of Birth:</strong></th>
<th><strong>Birthplace:</strong></th>
<th><strong>Gender:</strong></th>
<th><strong>Email Add:</strong></th>
<th><strong>Contact#:</strong></th>
<th><strong>Address:</strong></th>
</tr>
</thead>
<?php
include('db.php');
$sql=mysqli_query("SELECT emp.eid,emp.fname,
emp.mname,emp.lname,
emp.age,emp.gender,
emp.birthday,emp.birthplace,
emp.citizenship,emp.status,
emp.sss,emp.philhealth,
emp.tin,emp.height,
emp.weight,
con.address,
con.province,con.postcode,
con.telno,con.mobile,
con.email,con.alternate,
educ.elem,
educ.egrad,educ.high,
educ.hgrad,educ.college,
educ.cgrad,
ems.position,ems.hireDate,ems.job_desc,ems.basic,ems.salary,
w.company_name,w.position,w.desc,w.startDate,w.endDate,
fam.fatherName,fam.motherName,fam.sibling,fam.spouse,fam.children
FROM employee AS emp INNER JOIN contact AS con ON con.eid='emp.eid'
INNER JOIN educ AS educ ON educ.eid='emp.eid'
INNER JOIN employment AS ems ON ems.eid='emp.eid'
INNER JOIN work AS w ON w.eid='emp.eid'
INNER JOIN family AS fam ON fam.eid='emp.eid' WHERE emp.eid='$id'");
$counter=0;
while($row=mysqli_fetch_assoc($sql))
{
$cname = $row['name'];
$cbday = $row['birthday'];
$pob = $row['pob'];
$cgen = $row['gender'];
$email = $row['email'];
$contact= $row['contact'];
$add = $row['address'];
if($counter%2)
{
?>
<tbody>
<?php } else { ?>
<tr>
<?php } ?>
<td><?php echo $cname; ?></td>
<td><?php echo $cbday; ?></td>
<td><?php echo $pob; ?></td>
<td><?php echo $cgen; ?></td>
<td><?php echo $email; ?></td>
<td><?php echo $contract; ?></td>
<td><?php echo $add; ?></td>
</tr>
</tbody>
<?php
$counter++;
}//while-end
?>
</table>`
To make things much weird, let me tell you that when I tried to display values using mysqli_fetched_assoc() the query doesn't seem to work as in on my index page nothing else displays. Though the db has its record. But when I used mysql [though many have claimed it to be deprecated] it seems to work fine eventhough I had mysqli used for the insert statement. You guys get my point right? I used mysqli for insert statement and mysql for display and it works fine except for the eid of course.
Any idea?
$sql=mysql_query
Will never ever work with
mysqli_insert_id
^
You need to use the same API for both calls. Use MySQLi throughout.

Join two database tables and output resutls to HTML table

For my current progress I need to create a table like the one below
pid cid eid name value
1 1 4 name ab
2 1 5 amt 2
3 1 4 name cd
4 1 5 amt 4
Instead of creating the table like this
pid cid name amt
1 1 ab 22
2 1 cd 4
Anyhow created table as my wish with the below code
<table width="1204" height="100" border="1">
<tr>
<?php $sqlname="Select * From elements where cat_id='1' order by e_id ";
$resname=mysql_query($sqlname);
while($rowname=mysql_fetch_array($resname)){
?>
<td colspan="2"><?php echo $rowname['lable_name']; ?></td>
</tr>
<tr>
<?php $i=0;
$sqlprolist="select value from products_list where name='".$rowname['lable_name']."' and e_id='".$rowname['e_id']."'";
$resprolist=mysql_query($sqlprolist);
while($rowprolist=mysql_fetch_array($resprolist)){
$i++;
?>
<td><?php echo $rowprolist['value'];?></td>
<?php if($i%8==0){
?>
<tr></tr>
<?php }?>
<?php }?>
</tr>
<?php }?>
</table>
But I don't have any idea to retrieve data from the table for processing.
thanks
as by following martin the table created as like the below table
pid cid eid name value
12 1 4 name abc
1 1 4 name cde
13 1 5 code 12
2 1 5 code 14
how to split up the data
like
name code breeder quality size
abc 12 121 121 22
acfd 34 164 22 22
thanks
It's difficult to help you without seeing database structure. Please share it with us, you might get better answers.
Anyway, I suppose you have two tables, elements and products_list. It looks like you need to lookup the value column in the products_list for every row in the elements table. You can merge these table into one result set using a single SQL query:
SELECT e.p_id, e.cat_id, e.e_id, e.lable_name, p.value
FROM elements e, products_list p
WHERE e.cat_id='1' AND
p.name = e.lable_name AND p.e_id = e.e_id
ORDER BY by e.e_id
Note that the e.p_id is just a guess, you have not shared with us, where the "pid" column value gets from. Also not sure, if you actually need to match the rows using the p.name = e.lable_name. If e_id is primary key, you might do with p.e_id = e.e_id only.
What's the point of cid column? If it is indeed the cat_id column in database, why do you need it in HTML table, if you filter the elements to cat_id=1 anyway? Was that intentional?
You can now take the results of the query and simply output it to a HTML table row by row like:
<table width="1204" height="100" border="1">
<tr>
<th>pid</th>
<th>cid</th>
<th>eid</th>
<th>name</th>
<th>value</th>
</tr>
<?php
$sqlname =
"SELECT e.p_id, e.cat_id, e.e_id, e.lable_name, p.value ".
"FROM elements e, products_list p ".
"WHERE e.cat_id='1' AND ".
"p.name = e.lable_name AND p.e_id = e.e_id".
"ORDER BY e.e_id";
$resname = mysql_query($sqlname);
while ($row = mysql_fetch_array($resname))
{
?>
<tr>
<td><?php echo $row['p_id'];?></td>
<td><?php echo $row['cat_id'];?></td>
<td><?php echo $row['e_id'];?></td>
<td><?php echo htmlspecialchars($row['lable_name']);?></td>
<td><?php echo $row['value'];?></td>
</tr>
<?php
}
?>
</table>
This is just a first step. It's unlikely this is correct answer. But I hope it helps you understand, what are you trying to do and to your question.
This is hardly production-grade code. But I wanted to do as little changes as possible, so you can see, what is the actual change from your code.
Also note that the mysql_ functions are deprecated. See the big red box on PHP documentation page.

Using while() display even with NULLS

I have a table and I am displaying its contents using PHP and a while(); I have about three fields in the table that are NULL but can be change, but I want them to still display all the results in my table.
But, it only shows the records with data in EVERY field. Anyone how I can display it? I get a count of the table and it gives me 2, but only displays one.
<h3>Viewing All Updates</h3>
<h4>Below are all active updates for COTC</h4>
<table>
<thead>
<tr>
<th>Site Name</th>
<th>Page</th>
<th>Flag</th>
<th>Date Sent</th>
<th>View</th>
</tr>
</thead>
<tbody>
<?php
$sql = "SELECT sname,page_name,date_submitted,u_id,clients.c_id,flag,completed FROM updates INNER JOIN clients ON updates.c_id = clients.c_id INNER JOIN pages ON updates.page = pages.p_id ORDER BY date_submitted DESC";
$query = mysql_query($sql) or die(mysql_error());
while($row = mysql_fetch_array($query)){
$completed = $row['completed'];
if($completed == 1){
print '<tr class="quiet">';
}else{
print '<tr>';
}
print '<td>'.$row['sname'].'</td>';
print '<td>'.$row['page_name'].'</td>';
print '<td>'.$row['flag'].'</td>';
print '<td>'.$row['date_submitted'].'</td>';
print '<td class="center"><img src="images/page_edit.png" alt="Edit entry!" /></td>';
print '</tr>';
}
?>
</tbody>
</table>
Your PHP is correctly printing every row returned. I believe your problem is in the query.
SELECT sname,page_name,date_submitted,u_id,clients.c_id,flag,completed
FROM updates INNER JOIN clients ON updates.c_id = clients.c_id
INNER JOIN pages ON updates.page = pages.p_id
ORDER BY date_submitted DESC
This query will only return a row in updates if it has a matching one in clients and a matching one in pages. If you want the clients or the pages joins to be optional (a updates row that has c_id or page of NULL will still return) change them from INNER JOINs to LEFT JOINs.

Categories