MySQL Select Data from Multiple Unrelated Tables - php

I have a page on my site where I would like to list out the separate instances in which a customer ordered a part or brought their bike in for service. The data for each of these is contained in separate tables. Ultimately I'll be sorting these by date and using ORDER BY and COALESCE to make this work, but first I have to pull the data and I can't figure out how to do it.
Since the two tables are unrelated I won't be using a JOIN to combine data and I thought I might use a UNION but then learned that the data and number of columns for unions needs to be similar. I saw someone somewhere just throwing up a comma but I can't get mine to work.
Here's what I've got:
$result = mysql_query("SELECT
p.part_id,
p.part_num,
p.descr,
p.vendor,
p.date_entered,
p.date_ordered,
p.date_rcvd,
s.serv_id,
s.make,
s.model,
s.yr,
s.vin,
s.mileage,
s.in_date,
s.out_date
FROM parts p, services s
WHERE cust_id = '$cust_id'");
if (mysql_num_rows($result) == 0) {
$transactions = array();
} else {
while ($row = mysql_fetch_assoc($result)) {
$transactions[] = $row;
}
}
Later on
<? foreach ($transactions as $transaction): ?>
<? if($transaction['part_id'] && $transaction['part_id'] != "") { ?>
[DISPLAY PART INFO]
<? } elseif($transaction['serv_id'] && $transaction['serv_id'] != "" { ?>
[DISPLAY SERVICE INFO]
<? } ?>
<? endforeach; ?>
Any ideas?

Waht about using null columns ?
Ih the first table has columns name, date, pieces and the second name_cust, date_bike_entered you could do
Select name, date, pieces, null, null from table1
Union All
Select null, null, null, name_cust, date_bike_entered from table2

Solution A
You will need two queries to handle a request for (1) parts and (2) services. You will need some logic to differentiate the two.
Solution B
SELECT COUNT(*) FROM parts WHERE part_id = $transaction['part_id']
SELECT COUNT(*) FROM services WHERE serv_id = $transaction['serv_id']
This will give you the number of results for each. Add logic to pull data based on the result. However, you'll need logic to handle if you have results in both queries.
Solution C
Have a radio form that allows only part_id or serv_id, and query based on the user's selection.

Related

Left join MySql/PHP

Whilst populating a table based on ids and labels from different tables, it appeared apparent there must potentially be a better way of achieving the same result with less code and a more direct approach using LEFT JOIN but i am puzzled after trying to work out if its actually capable of achieving the desired result.
Am i correct in thinking a LEFT JOIN is usable in this instance?
Referencing two tables against one another where one lists id's related to another table and that other table has the titles allocated for each reference?
I know full well that if theres independent information for each row LEFT JOIN is suitable, but where theres in this case only several ids to reference for many rows, i just am not clicking with how i could get it to work...
The current way i am achieving my desired result in PHP/MySQL
$itemid = $row['item_id'];
$secid = mysql_query(" SELECT * FROM item_groups WHERE item_id='$itemid' ");
while ($secidrow = mysql_fetch_assoc($secid)) {
//echo $secidrow["section_id"]; //testing
$id = $secidrow["section_id"];
$secnameget = mysql_query(" SELECT * FROM items_section_list WHERE item_sec_id='$id' ");
while ($secname = mysql_fetch_assoc($secnameget)) {
echo $secname["section_name"];
}
}
Example of the data
Item groups
:drink
:food
:shelf
Item List
itemId, groupId
Group List
groupId, groupTitle
The idea so outputting data to a table instead of outputting "Item & Id Number, in place of the ID Number the title actually appears.
I have achieved the desired result but i am always interested in seeking better ways to achieve the desired result.
If I've deciphered your code properly, you should be able to use the following query to get both values at the same time.
$itemid = $row['item_id'];
$secid = mysql_query("
SELECT *
FROM item_groups
LEFT JOIN items_section_list
ON items_section_list.item_sec_id = item_groups.section_id
WHERE item_id='$itemid'
");
while ($secidrow = mysql_fetch_assoc($secid)) {
//$id = $secidrow["section_id"];
echo $secidrow["section_name"];
}

PHP MYSQL - Highlight a database table row IF table1.id exists in table2

I'm kinda of stuck here for a while maybe you guys can help me out? I want to highlight a table of database record, coming from one table, and check if the id out of this table also exists in the 2nd table.
Let me be more specific:
Table 1: Projects (projectid pk)
Table 2: Reservations (projectid fk)
A simple sample code, to keep this simple:
while( $record=mysql_fetch_array($result) )
{
$projectid=$record['projectid'];
echo "<tr>". $projectid ."</tr>;
}
So this is working great, I get all table rows with each projectid which exists in my DB, but how to pass this $projectid variables to another query which checks if this exists in the other table, and if it exists, echo out something different? Here's my code which probably doesn't make much sense, but at least the logic is there... I hope?:
while( $record=mysql_fetch_array($result) )
{
$projectid=$record['projectid'];
$hasreservationquery = ("
SELECT *
FROM reservelist rl
INNER JOIN project p on rl.projectid = p.projectid
WHERE rl.projectid = $projectid
");
$hasreservationqueryresult = mysql_query($hasreservationquery) or die(mysql_error());
if ($hasreservationqueryresult > 1)
{
echo "<tr id='hasreservation'>";
}
else
{
echo "<tr>";
}
echo "". $projectid ."";
}
Unfortunately this returns all tables highlighted, not just the one that really has a reservation in it. What am I doing wrong??
Thanks in advance.
You don't ever appear to be checking the row count. you need to change your if statement:
if (mysql_num_rows($hasreservationqueryresult) > 0)
This will now check if 1 or more results are returned (change it to be > x if you want x + 1 results returned before you highlight).
mysql_query doesn't return the amount of affected rows.
I think something like
if($hasreservationqueryresult && mysql_num_rows($hasreservationqueryresult) > 0)
Except for that I'd definitely arrange your code a bit better and rethink your variable names :)

Counting from field in table then updating to a different field in a different table

Quite a complex question:
At the moment I have a table called "timetable". This is updated when someone books a slot (this is for a radio booking system). What I would like is a PHP file that I can have run every 15 minutes as a cron job. In PHP script what I'd like it to do is count how many slots a radio presenter has booked via the "username" field in the "timetable" table. Then I would like it to update a field in another table called "users" in a field called "slot_count" with the amount of slots which were found in the "timetable" table under their "username".
At the moment I have a script which pulls all the booked slots with their presenter "username"'s into a table:
<?php
include("../config.php");
include("functions.php");
if($logged["level"] == "HDJ" OR $logged["level"] == "SA") {
echo "<table width=\"580px\" class=\"board\" border=\>";
$order = "SELECT * FROM timetable WHERE username <> 'No DJ'";
$result = mysql_query($order);
// Error checking
if (!$result) {
// output error, take other action
}
else {
while ($row=mysql_fetch_array($result)){
// Append all results onto an array
$rowset[] = $row;
}
}
foreach ($rowset as $row) {
echo "<tr><td>" . htmlspecialchars($row['username']) . "</td></tr>";
}
} else {
echo ("<div class=\"caution\">Access is denied.</div>");
}
?>
Any ideas?
Storing this redundant data in your users table is unnecessary. As long as the tables are indexed appropriately the join and count are trivial -
SELECT users.*, COUNT(timetable.username) AS num_slots
FROM users
LEFT JOIN timetable
ON users.username = timetable.username
GROUP BY users.id
Can't it be done using one sql statement doing both COUNT() and UPDATE:
UPDATE users
SET slot_count = (SELECT COUNT(*) FROM timetable WHERE timetable.username = users.username)
Assumption: the username field contains the same value for the same radio presenter in both users and timetable tables. Otherwise they wouldn't match. You should be able to run this query directly against MySQL from the cron job (instead of doing the PHP script).

What is the query statement to write in order to solve the followin database problem?

I have the following 3 tables in the database.
Programs_Table
Program_ID (Primary Key)
Start_Date
End_Date
IsCompleted
IsGoalsMet
Program_type_ID
Programs_Type_Table(different types of programs, supports a dropdown list in the form)
Program_type_ID (Primary Key)
Program_name
Program_description
Client_Program_Table
Client_ID (primary key)
Program_ID (primary key)
What is the best way to find out how many clients are in a specific program (program type)?
Would the following SQL statement be the best way, or even plausible?
SELECT Client_ID FROM Client_Program_Table
INNER JOIN Programs_Table
ON Client_Program_Table.Program_ID = Programs_Table.Program_ID
WHERE Programs_Table.Program_type_ID = "x"
where "x" is the Program_type_ID of the specific program we're interested in.
OR is the following a better way?
$result = mysql_query("SELECT Program_ID FROM Programs_Table
WHERE Program_type_ID = 'x'");
$row = mysql_fetch_assoc($result);
$ProgramID = $row['Program_ID'];
$result = mysql_query("SELECT * FROM Client_Program_Table
WHERE Program_ID = '$ProgramID'");
mysql_num_rows($result) // returns how many rows of clients we pulled.
Thank you in advance, please excuse my inexperience and any mistakes that I've made.
Here is how you can do it:
<?php
// always initialize a variable
$number_of_clients = 0;
// escape the string which will go in an SQL query
// to protect yourself from SQL injection
$program_type_id = mysql_real_escape_string('x');
// build a query, which will count how many clients
// belong to that program and put the value on the temporary colum "num_clients"
$query = "SELECT COUNT(*) `num_clients` FROM `Client_Program_Table` `cpt`
INNER JOIN `Programs_Table` `pt`
ON `cpt`.`Program_ID` = `pt`.`Program_ID`
AND `pt`.`Program_type_ID` = '$program_type_id'";
// execute the query
$result = mysql_query($query);
// check if the query executed correctly
// and returned at least a record
if(is_resource($result) && mysql_num_rows($result) > 0){
// turn the query result into an associative array
$row = mysql_fetch_assoc($result);
// get the value of the "num_clients" temporary created column
// and typecast it to an intiger so you can always be safe to use it later on
$number_of_clients = (int) $row['num_clients'];
} else{
// query did not return a record, so we have no clients on that program
$number_of_clients = 0;
}
?>
If you want to know how many clients are involved in a program, you'd rather want to use COUNT( * ). MySQL (with MyISAM) and SQL Server have a fast way to retrieve the total number of lines. Using a SELECT(*), then mysql_num_rows leads to unnecessary memory ressources and computing time. To me, this is the fastest, though not the "cleanest" way to write the query you want:
SELECT
COUNT(*)
FROM
Client_Program_Table
WHERE
Program_ID IN
(
SELECT
Program_ID
FROM
Programs_Table
WHERE
Program_type_ID = 'azerty'
)
Why is that?
Using JOIN make queries more readable, but subqueries often prove to be computed faster.
This returns a count of the clients in a specific program type (x):
SELECT COUNT(cpt.Client_ID), cpt.Program_ID
FROM Client_Program_Table cpt
INNER JOIN Programs_Table pt ON cpt.Program_ID=pt.Program_ID
WHERE pt.Program_type_ID = "x"
GROUP BY cpt.Program_ID

Order MySQL results by number of related rows in foreign table

Alright, so I have a table outputting data from a MySQL table in a while loop. Well one of the columns it outputs isn't stored statically in the table, instead it's the sum of how many times it appears in a different MySQL table.
Sorry I'm not sure this is easy to understand. Here's my code:
$query="SELECT * FROM list WHERE added='$addedby' ORDER BY time DESC";
$result=mysql_query($query);
while($row=mysql_fetch_array($result, MYSQL_ASSOC)){
$loghwid = $row['hwid'];
$sql="SELECT * FROM logs WHERE hwid='$loghwid' AND time < now() + interval 1 hour";
$query = mysql_query($sql) OR DIE(mysql_error());
$boots = mysql_num_rows($query);
//Display the table
}
The above is the code displaying the table.
As you can see it's grabbing data from two different MySQL tables. However I want to be able to ORDER BY $boots DESC. But as its a counting of a completely different table, I have no idea of how to go about doing that.
There is a JOIN operation that is intended to... well... join two different table together.
SELECT list.hwid, COUNT(log.hwid) AS boots
FROM list WHERE added='$addedby'
LEFT JOIN log ON list.hwid=log.hwid
GROUP BY list.hwid
ORDER BY boots
I'm not sure if ORDER BY boots in the last line will work like this in MySQL. If it doesn't, just put all but the last line in a subquery.
But the result of the query into an array indexed by $boots.
AKA:
while(..){
$boot = mysql_num_rows($query);
$results[$boot][] = $result_array;
}
ksort($results);
foreach($results as $array)
{
foreach($array as ....)
{
// display table
}
}
You can switch between ksort and krsort to switch the orders, but basically you are making an array that is keyed by the number in $boot, sorting that array by that number, and then traversing each group of records that have a specific $boot value.

Categories