Combine multiple queries to get single sum answer - php

Quite new to all the SQL/PHP stuff - dabbled with basic queries and outputting them to PHP previously but now trying something a bit more complicated and hoping someone can help with this as I've been trying to work it out with no luck so far:
I have 2 MS SQL tables:
Table 1 - Faults
faultid ... requestnumber
1 ........... 6
2 ........... 5
3 ........... 6
Table 2 - actions
faultid ....who ..... when...... timetaken
1.......... John....... Mon......... 1.00
2.......... Peter...... Mon.......... 2.00
3.......... Luke....... Tues........ 1.00
2.......... John....... Tues........ 0.5
1.......... Mike....... Mon......... 0.75
What I am trying to achieve is create a variable I can use in a front end php based webpage that gets a sum of the timetaken column in Table 2 where the requestnumber in Table 1 is equal to a specific number (i.e. 6)
I'm guessing it will start with something like:
$sql1 = "select faultid FROM Faults WHERE requestnumber = '6'";
$sqlresult = sqlsrv_query($conn, $sql1);
while ($row = sqlsrv_fetch_array($sqlresult)){
}
After that I get a bit stuck. How do I take each result from this and then run another query to get the sum of the timetaken column in Table 2 for just the corresponding faultid's? I want to hazard a guess at using foreach but not sure on the syntax (or even if I'm guessing correctly).
So in this example I would get back a result of 2.75 as a variable in PHP.
Any help would be appreciated. Thanks in advance.
Andy

Best to use just one SQL-statement
$sql = 'SELECT SUM(t2.timetaken)';
$sql .= ' FROM Faults t1 INNER JOIN actions t2 ON (t2.faultid = t1.faultid)';
$sql .= ' WHERE t1.requestnumber = ?';
Use this as prepared statement and pass your requestnumber (6 or something) as argument when executing this statement.
To get all or multiple sums you can use group by (maybe combine with WHERE):
SELECT t1.requestnumber, SUM(t2.timetaken)
FROM Faults t1
INNER JOIN actions t2 ON (t2.faultid = t1.faultid)
GROUP BY t1.requestnumber
Edit:
According to your own comment, you can use a SELECT with subquery, but use IN, not =. When using '=' the subquery must return only one row.
select SUM (timetaken) FROM actions WHERE faultid IN (select Faultid from Faults WHERE requestnumber = '6')
-- ^^
But this way is usually slower than the one I posted above

Related

Selecting data from 2 tables where columns are the same, query not quite right?

I'm trying to fetch data from 2 tables where the prop_slug and prop_gallery_id match. I've written the following statement only I cant seem to get it to work and keep getting an error with my syntax - can anybody see if there's a glaring mistake in my query?...
$listings = $db->query('
SELECT *
FROM listing_details
JOIN prop_gallery
ON prop_gallery.prop_gallery_id = listing_details.prop_slug
WHERE (listing_details.prop_slug LIKE \'prop_gallery_id\' OR prop_gallery.prop_gallery_id LIKE \'prop_slug\')
AND
WHERE listing_details.prop_mandate = 1
LIMIT 3')->fetchAll();
You don't need the second WHERE
$listings = $db->query('
SELECT *
FROM listing_details
JOIN prop_gallery
ON prop_gallery.prop_gallery_id = listing_details.prop_slug
WHERE (listing_details.prop_slug LIKE \'prop_gallery_id\' OR prop_gallery.prop_gallery_id LIKE \'prop_slug\')
AND listing_details.prop_mandate = 1
LIMIT 3')->fetchAll();

Does't selecting the good value in sql

Hello I have a sql syntax and it always take the last record and doest check the other condition.
SELECT *
from projetstaches ,users,timesheets
WHERE `prtTimeSheetId` = ( SELECT MAX( `prtTimeSheetId` ) FROM projetstaches ) AND usrId = 16 AND timId = prtTimeSheetId
I'm working with php and sql but I know this is my syntax is not good.
It's always give me my last record . It's do not take the last record of my user 16 . Cause my last record its for my user 7 . Have any idea why?
So I need to take the last projettime sheet of my user 16
**EDIT **
here what look like my data http://pastebin.com/6LBwGtc3
I suppose your query should look like this:
SELECT *
from
projetstaches
inner join
timesheets
on (timesheets.timId = projetstaches.prtTimeSheetId)
inner join
users
on (users.usrId = timesheets.timUserId)
WHERE
users.usrId = 16
order by timesheets.timId desc
limit 1
To understand how it works I suggest you to play with this query:
remove where - check result
remove limit - check result

How to count if value of a variable is repeated?

I am learning how to work with MySQL, and at the moment I succeed to show data from my table, using:
while($objResult2 = mysqli_fetch_assoc($objQuery_product)) {
Results are shown by using this variable $objResult2["id_product"]; this way i can take from DB any field I want like: $objResult2["name"]; $objResult2["email"]; etc.
But what i do if i have in the table more rows with the same id_product?
I want to write a if statment, which counts if id_product repeats. How to do that? If it is a lot of work, atleast please give me an idea of the right tutorial that I must read. Because i am trying second day to fix this, and searched google but i didnt find what i need, or maybe i coulndt understand it....
This is my query
$sql_product = "SELECT * FROM ps_product AS prod";
$join_product = " LEFT JOIN ps_product_lang AS lang ON lang.id_product = prod.id_product";
$join2_product = " LEFT JOIN ps_stock_available AS stok ON stok.id_product = prod.id_product";
$where_product =" WHERE prod.id_category_default = $idp AND lang.id_lang = 8";
$sql_product = $sql_product.$join_product.$join2_product.$where_product;
$objQuery_product = mysqli_query($objConnect, $sql_product) or die ("Error Query [".$sql_product."]");
You can simple remove the same id_product using DISTINCT keyword in your query. Such as:
SELECT DISTINCT id_product FROM my_table
This will give you results with different ids only.
The second way of doing it is taking the output values inside an array.
In your while loop:
$my_array[] = $objResult2["id_product"];
Then using array_filter remove all the duplicates inside the array.
YOu can also use array_count_values() if you want to count the duplicate values.
Ok here we go. For example you are fetching data with this query.
select id_product, name from PRODUCTS;
Suppose above query gives you 5 records.
id_product name
1 bat
2 hockey
2 hockey
3 shoes
4 gloves
Now you got 2,2 and hockey, hockey. Instead of thinking this way that you have to introduce an if statement to filter repeating records or same name or id_product records.
Rewrite your sql query like this.
select distinct id_product, name from PRODUCTS;
Or if you need count of each then my friend you will write your query something like this...
Graham Ritchie, if Andrei needs count of each repeating record then we will do something like this in our query.
SELECT PRODUCT_ID,
COUNT(PRODUCT_ID) AS Num_Of_Occurrences
FROM PRODUCTS
GROUP BY PRODUCT_ID
HAVING ( COUNT(PRODUCT_ID) > 1 );
SELECT id_product,COUNT(*) AS count
FROM tablename
GROUP BY id_product;
This query will then return you two items in your query
$objResult2["id_product"] //and
$objResult2["count"]
The if statement is then just
if($objResult2["count"] > 1){
//Do whatever you want to do with items with more than 1 occurence.
//for this example we will echo out all of the `product_id` that occur more than once.
echo $objResult2["id_product"] . " occurs more than once in the database<br/>";
}

Query two tables for different/separate values

I have two tables:
task
id name dueDate completed projectID
project
id name dueDate completed
I need to query both tables for rows with the same data. I tried doing a sample statement just looking for rows with completed=0, but never got any results. I think it has to do with using OR instead of AND, but it's just a little above my level right now...Any ideas?
TO CLARIFY, I'm not looking for duplicate rows, I'm looking for 'all tasks and projects with completed = 0'
The query is:
SELECT * FROM "task" t, "project" p WHERE t.dueDate = "2012-08-17" OR p.dueDate = "2012-08-17" AND t.completed = 0 OR p.completed = 0
I did manage to get one of the answers' code to work, however I realized that my entire app was written to talk to one table, and that it would be much easier to just combine the task and project table and use an isProject column to differentiate projects from tasks. This also adds the ability to nest projects inside of projects, because projects will now have a projectID column as well.
In the end, KISS prevails...
Thanks for all the help! I will mark the answer that worked, even though I won't be using it.
Try using parenthesis.
SELECT * FROM "task" t, "project" p WHERE (t.dueDate = "2012-08-17" OR p.dueDate = "2012-08-17") AND (t.completed = 0 OR p.completed = 0)
If You want only values matches from both tables with completed=0 from dueDate='2012-08-17':
You can use join to bound that tables results into one.
Inner join will return only results which matches on both sides.
So You can use it to match them in both tables by it and then filter for Your wanted value by classic where:
select * from task t inner join project p on t.dueDate = p.dueDate and t.completed = p.completed
where t.dueDate = '2012-08-17' and t.completed = 0
Try this instead:
SELECT dueDate, completed
FROM task AS t
WHERE (dueDate = "2012-08-17" AND completed = 0)
UNION ALL
SELECT dueDate, completed
FROM project AS p
WHERE (dueDate = "2012-08-17" AND completed = 0)
This should give you all records from each table where dueDate = "2012-08-17" and completed = 0.

MySQL 18 queries required, or can I use just one?

I'm creating a golf score tracking database for some friends and am having trouble with the best way to retrieve a specific value from the result.
I have tables:
Players - stores player info
Hole - stores basic info about a hole (CourseID, HoleNum, Par...)
Score - stores each hole they played (HoleID, NumStrokes...)
My goal is to output a table showing their result for each hole (1-18). The following query gets me a list of all of the holes they played and the number of strokes it took them to complete the hole.
SELECT Hole.HoleID, NumStrokes
FROM Players
INNER JOIN Score ON Score.PlayerID = Players.PlayerID
INNER JOIN Hole ON Score.HoleID = Hole.HoleID
WHERE Players.PlayerID = '$PlayerID'
Results like this:
HoleID NumStrokes
1 4
1 6
1 3
2 5
7 3
Do I have to run 18 different queries, one for each hole that I am outputting, by adding:
AND Hole.HoleID = '$HoleID'
to my query, or is there a better SQL query that I could use? The Hole table also as a round identifier, so don't worry about determinig which NumStrokes of HoleID I need. I'm using PHP, by the way. Hopefully my question was clear enough.
Thank you!
$conn = new mysqli('host','user','pass','db_name');
$PlayerID = (int) $_GET['PlayerID'];
$rs = $conn->query("
SELECT Hole.HoleID, NumStrokes
FROM Players
INNER JOIN Score ON Score.PlayerID = Players.PlayerID
INNER JOIN Hole ON Score.HoleID = Hole.HoleID
WHERE Players.PlayerID = $PlayerID
") or die($conn->error);
while($row = $rs->fetch_object()) {
echo $row->HoleID.' - '.$row->NumStrokes.'<br/>';
}
This will output the results for a player. You can do the same with the mysql_* functions, but since they are deprecated its better to use mysqli or PDO

Categories