Complex select statement - php

I have 4 tables
Tbl_Items:
Asset Id,
Asset_name,
Workshop,
PAT_PASS
(workshop, and PAT_PASS are either YES or NO. Workshop = YES and PAT_PASS = NO means this item is not available for hire..)
Tbl_Project_details:
Project_id,
Project_start_date,
project_end_date
TBL_Project_items:
Project_id,
Asset_id,
Start_date,
End_date
I need to do a select statement that allows me to show all the items in tbl_Items EXCEPT:
1) Those that are already in use on another project on the dates that I need them.
2) Are in the workshop. (Workshop = YES)
3) Are not PAT Tested (PAT_PASS = NO)
So far I have started with a simple statement like this:
$post_project_id = "13-1309.01"; //this is just an example number..
$sql =
"SELECT * FROM Project_details
Where Project_id = '$post_project_id' ";
$result = mysql_query($sql);
while ($row = mysql_fetch_array($result))
{
$hire_start_date = $row['Start_date']; // we find out our projects start date
$hire_end_date = $row['End_date']; // we find out our projects end date
}
$result=mysql_query("SELECT Items.Asset_id, Items.Name
FROM
Items,Project_items
WHERE
Project_details.Start_date < '$hire_start_date'
AND
Project_details.End_date > '$hire_end_date'")
or die(mysql_error());
while($row = mysql_fetch_array($result))
{
// fill up an option box with the results
}
Even this basic script doesn't seem to work! This is the first time I have tried selecting from multiple tables, so this is a steep learning curve!
Thanks!

I would go with a subquery:
SELECT * FROM Tbl_Items AS i WHERE
this should matches your (1.) condition: "take only those records, which with that select dont have any occurences":
0 = (
SELECT COUNT(1) FROM TBL_Project_items AS pi
WHERE i.Asset_Id = pi.Asset_Id
AND Start_date < $hire_start_date
AND End_date > $hire_end_date
)
workshop condition (2.):
AND WORKSHOP != "YES"
pat tested condition (3):
AND PAT_PASS != "NO"

$StartDate and $EndDate are your date constraints:
SELECT ITEM.asset_id,
ITEM.asset_name,
ITEM.workshop,
ITEM.pat_pass
FROM Tbl_Items ITEM
LEFT JOIN Tbl_Project_Items PJITEM
ON PJITEM.asset_id = ITEM.asset_id
AND PJITEM.start_date BETWEEN $StartDate AND $EndDate
OR PJITEM.end_date BETWEEN $StartDate AND $EndDate
WHERE ITEM.workshop = 'no'
AND ITEM.pat_pass = 'yes'
AND PJITEM.asset_id IS NULL
Who's Pat?

One problem:
WHERE
Project_details.Start_date < '$hire_start_date'
AND
Project_details.End_date > '$hire_end_date'")
The columns "Start_date" and "End_date" aren't in the "Project_details" table. In that table, those columns seem to be named "Project_start_date" and "Project_end_date".

Related

SQL query with results based on current date

I'm practicing on a php website with reservations. I've made three tabs on which I want to display reservations for today and for the coming week.
So far I have this mysql query:
$sql = "SELECT *
FROM users
LEFT JOIN reserveringen ON (users.userID = reserveringen.userID)
WHERE reserveringen.kamertype = 1
AND reserveringen.datum <= DATEADD(day,+7, GETDATE())";
but I it doesnt display any results
Edit:
I have made an if-else statement saying if there are results display them else echo a message saying "there are no reservations for the coming week". This is the query for showing all reservations and it runs just fine:
$sql = "SELECT *
FROM users
LEFT JOIN reserveringen ON (users.userID = reserveringen.userID)
WHERE reserveringen.kamertype = 1`
The function name DATEADD() is a TransactSQL function. In MYSQL it is called DATE_ADD() and the parameters are different as well
So this is more likely to work
$sql = "SELECT *
FROM users
LEFT JOIN reserveringen ON (users.userID = reserveringen.userID)
WHERE reserveringen.kamertype = 1
AND reserveringen.datum <= DATE_ADD(CURRDATE(), INTERVAL 7 DAY)";

How to combine multiples sum and dates from mysql

Im trying to generate data for a graph but everytime i attempt to do it it basically just gives me 1 sum. For the graph i need the date and the value.
This is my current code:
$chart_data = "";
$earnings_query = mysql_query("SELECT SUM(R.rate) as ratess,R.date FROM reports R WHERE R.pid = '$publisher_id' AND R.status = '2'");
if (mysql_num_rows($earnings_query) > 0)
{
while ($row = mysql_fetch_array($earnings_query))
{
$date = date("m/d/Y",strtotime($row['date']));
$chart_data.= '{"date": "'.$date.'", "value": '.$earnings_total['tot'].'},';
}
}
echo $chart_data;
the output is {"date": "12/31/1969", "value": }, but i should be getting daily data all the way back from June 6.
Thanks to all the comments below, the code below solves my problem.
$earnings_query = mysql_query("SELECT SUM(R.rate) as ratess, R.date FROM reports R WHERE R.pid = '$publisher_id' AND R.status = '2' GROUP BY date(R.date)");
if (mysql_num_rows($earnings_query) > 0)
{
while ($row = mysql_fetch_array($earnings_query))
{
$date = date("m/d/Y",strtotime($row['date']));
$chart_data.= '{"date": "'.$date.'", "value": '.$row['ratess'].'},';
}
}
echo $chart_data;
You need a group by clause:
SELECT SUM(R.rate) as ratess, R.date
FROM reports R
WHERE R.pid = '$publisher_id' AND R.status = '2'
GROUP BY R.date;
Without the group by, your query is an aggregation query that runs over the entire set of data. The result (without a group by) is always going to be one row.
If your column called date has a time component, then you might want to use the date() function:
SELECT SUM(R.rate) as ratess, date(R.date) as date
FROM reports R
WHERE R.pid = '$publisher_id' AND R.status = '2'
GROUP BY date(R.date);
Add a GROUP BY date to your SQL command.
SELECT SUM(R.rate) as ratess, R.date
FROM reports R
WHERE R.pid = '$publisher_id' AND R.status = '2'
GROUP BY R.date
This will sum for each date in the range, whereas you were summing for all dates and then selecting the first date. If the date field isn't just a date, but also includes time information, you'll want to use DATE(R.date) instead.

Best way to sum and seperate by date in MYSQL with/witout php

Hi i have such table information:
what i want to do with php with while or just in mysql, is to SUM (time_used) of the rows with status 44 until its reached row with status 55. after that it should begin from start with new summing.
first query should return 37, second 76 (keep in mind it should be universal, for unlimited occurrences of 55 status row)
i thought of a way with time/date filtering and have this:
select sum(time_used) as sumed
from timelog
where start_time > (select end_time from timelog where (status='55')
ORDER BY id DESC LIMIT 1) ORDER BY id DESC
but this works only for last combination of 44 and 55
i know i will need two way filtering( < end_time and > end_time) so it will work for all cases, but cant think of a way to do it in php
can anyone help me?
EDIT:
sqlfiddle whoever want it:
http://sqlfiddle.com/#!2/33820/2/0
There are two ways to do it: Plain SQL or PHP. If you treat thousands of rows, it may be interresting to choose between the two by testing performance.
Plain SQL
select project_id, task_id, user_id, sum(time_used) as time_used,
min(start_time) as start_time, max(end_time) as end_time, max(comment) as comment from
(select t.id, t.project_id, t.task_id, t.user_id, t.time_used,
count(t2.id) as count55, t.start_time, t.end_time, t.comment
from timelog t
left join timelog t2 on t.id>t2.id and t2.status=55 and t.task_id=t2.task_id
group by t.id) as t
group by count55;
I assume here that a task can belong to one user only
SQL and PHP
$link = mysqli_connect( ... );
$query = "select id, project_id, task_id, user_id, time_used, start_time, end_time, status
from timelog order by id";
$result = mysqli_query($link, $query);
$table = array();
$time_used = 0;
$start_sum = true;
$i = 0;
while($row = mysqli_fetch_assoc ($result)){
if($start_sum){
$table[$i] = $row;
$start_sum = false;
} else {
$table[$i]['time_used'] += $row['time_used'];
$table[$i]['end_time'] += $row['end_time'];
}
if($row['state'] == 55){
$i++;
$start_sum = true;
}
}
If two tasks can run in simultaneously, solution 1 will work, but solution 2 will need to be adapted in order to take this in account.
here is my intepretation:
http://sqlfiddle.com/#!2/33820/45
set #n=0;
select project_id, task_id, user_id,sum(time_used) from (
SELECT time_used,project_id, task_id, user_id,
#n:=if(status=55,#n+1,#n),
if(status=55,-1,#n) as grouper FROM timelog
) as t
where grouper>-1
group by grouper;
I'm neither a php nor MySQL programmer, but I can explain the logic you want to follow. You can then code it.
First, query your db and return the results to php.
Next, set two sum variables to 0.
Start looping through your query results. Increment the first sum variable until you reach the first row that has status 55. Once you do, start incrementing the second variable.
The tricky part will be to sort your query by the row number of the table. Here is a link that will help you with that part.

Loop through SQL and calculate sum in PHP

I have an issue with my code. I have 2 tables. First employee_id:
|Employee id|
1
2
3
And the second table called employee_times:
|Employee_id|Hours_dev|hours_pm|
|1|2|3|
|1|3|4|
|2|3|3|
What I am trying to do is to calculate the total time that each employee has worked (hours_dev+hours_pm). For example employee_id 1 has worked 12 hours
So far I have tried to retrieve all the employee_id from the first table and use a for loop to go through the employee_times in an SQL statement (SEE CODE BELOW). However the code does not work as it prints 0 for both employee_id and total_hours.
I am using MYSQL on a localhost server.
$sql = "SELECT employee_id FROM employee";
$result = mysql_query($sql);
while($row = mysql_fetch_array)
{
$employee_id = $row['employee_id'];
}
$employee_id_length = sizeof($employee_id);
for($i = 0; $i < $employee_id_length; $i++)
{
$sql4 = "SELECT employee_id, hours_dev, hours_pm FROM employee_times WHERE employee_id= '$employee_id[$i]'";
$result = mysql_query($sql4);
while($info = mysql_fetch_array($result));
{
$employee_id = $info['employee_id'];
$hours_dev=$info['hours_dev'];
$hours_pm=$info['hours_pm'];
$total_hours = ($total_hours + $hours_dev + $hours_pm );
}
//print "$employee_id worked for $total_hours";
}
Any help is much appreciated.
you can get sum directly
select employee_id, sum(hours_dev)+ sum(hours_pm) as total
from employee_times WHERE employee_id= '1'
group by employee_id
refer this Fiddle Demo
this should get the data you need
SELECT
hours_dev,
hours_pm,
sum(hours_dev) + sum(hours_pm) as total_hours
FROM
employee_times
WHERE
employee_id = 123
GROUP BY
employee_id
Take a look at aggregate functions:
http://www.w3schools.com/sql/sql_functions.asp
http://www.w3schools.com/sql/sql_func_sum.asp
This SQL query should pull the info much quicker than by script;
SELECT Employee_id, SUM(Hours_dev), SUM(Hours_pm), SUM(Hours_dev + Hours_pm)
FROM employee_times
GROUP BY Employee_id

How do i create a list(array) of values with the number of times they appear in another array

I am trying to generate a list of "Products" that details the amount of times each "Product appears in a mysql query.
Outline:
1. Get the last 30 days of orders from the database.
2. Get the products that appear in those orders.
3. Get a count of the times a product appears in the orders.
4. Display a list with "Product Name" and the "Qty Sold"
What i have so far (i am 1 week into php, so please excuse me if it's a mess)
$orderid = mysql_query("SELECT orderid FROM isc_orders WHERE orddate >= 1334266286 ");
while ($row = mysql_fetch_array($orderid)) {
$pslm = mysql_query("SELECT * FROM isc_order_products WHERE orderorderid = '$row[0]' GROUP BY ordprodid");
while ($row = mysql_fetch_array($pslm)) {
echo $row[2] . "</br>";
So this gives me a list of the products sold, but not grouped, and no qty shown of course.
I have gone through a number of posts here, and spent about 3 hours trying to do this. Hopefully someone here can help.
Thanks
Jason
Why not use a join and then group the results:
SELECT *, COUNT(1) AS quantity
FROM isc_orders AS o
LEFT JOIN isc_order_products AS p ON o.orderid = p.orderorderid
WHERE orddate >= 1334266286
GROUP BY p.productid
Or something like that. It's hard to guess exactly how it should be written without knowing how your database is structured.
Well, Elijah Madden already posted almost the same thing, but since I had already written it... here it goes:
SELECT
product.name,
COUNT(*)
FROM isc_orders order
INNER JOIN isc_order_products product
ON product.orderorderid = order.orderid
WHERE order.orddate >= 1334266286
GROUP BY order.ordprodid
Not the prettiest thing... you would probably want to get the product info (ie. name) from a product table, but here ya go:
$order_query = mysql_query("
SELECT orderid
FROM isc_orders
WHERE orddate >= " . (time() - (30 * 86400)));
if (mysql_num_rows($order_query) > 0)
{
$orders = array();
while ($order = mysql_fetch_assoc($order_query))
$orders[] = mysql_real_escape_string($order['orderid']);
$product_query = mysql_query("
SELECT *
FROM isc_order_products
WHERE orderorderid IN ('" . implode("', '", $orders) . "')");
if (mysql_num_rows($product_query) > 0)
{
$products = array();
$times_ordered = array();
while ($product = mysql_fetch_assoc($product_query))
{
if (!isset($times_ordered[$product['ordprodid']]))
$times_ordered[$product['ordprodid']] = 0;
$times_ordered[$product['ordprodid']]++;
if (!isset($products[$product['ordprodid']]))
$products[$product['ordprodid']] = $product;
}
foreach ($products as $id => $product)
$products[$id]['times_ordered'] = $times_ordered[$id];
}
mysql_free_result($product_query);
}
mysql_free_result($order_query);
This is what actually worked.
SELECT ordprodname, SUM(ordprodqty), ordprodid
FROM isc_orders, isc_order_products
WHERE orderid = orderorderid AND orddate >= UNIX_TIMESTAMP() - ('$days' * 86400)
GROUP BY ordprodname
ORDER BY SUM(ordprodqty) DESC");

Categories