MYSQL: Help with a left join? Might be better as two queries? - php

Im not to versed in mysql JOINS, but I think that is what is required for what I am trying to do.
With the help of SO, I got this excellent piece of SQL for calculating a count of items in my database (by categories):
SELECT SUM(`tid` IS NULL) AS `total_null`,
SUM(`tid` = 0) AS `total_zero`,
COUNT(DISTINCT `tid`) AS `other`
FROM `mark_list`
WHERE `user_id` = $userid
Now what I need the query to do is check another table: mark_options to see if the value groupthem = 1. If groupthem = 1 then the above query should be used. If groupthem = 0 then I would like to use the following query:
SELECT tid,
COUNT(*) AS other
FROM mark_list
WHERE userid = $userid
Is it better to run 2 queries, the first one to check if groupthem = 1 or 0, then have PHP decide which final query to run, or to use an SQL JOIN (or other method) to do the same function in a single query?
Thanks!!

Plz send teh reps. Kthx bai.
SELECT SUM(`mark_list`.`tid` IS NULL) AS `total_null`,
SUM(`mark_list`.`tid` = 0) AS `total_zero`,
COUNT(DISTINCT `mark_list`.`tid`) AS `other`,
COUNT(`mark_list`.`tid`) AS `ungrouped`,
`mark_options`.`groupthem`
FROM `mark_list`, `mark_options`
WHERE `mark_list`.`user_id` = $userid
GROUP BY `mark_options`.`groupthem`

Related

Combine multiple queries to get single sum answer

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

Mysql query returns error #1093 - You can't specify target table

I need to check and update with same query my database.
The error says it is not possble to update same table which is included in the select statement. Is there any workaround of this to happen in 1 mysql query? Here is the query:
$query='update option_values_to_products set available="0" where id in (
select ovtp.id from option_values ov,option_values_to_products ovtp,options o where
ovtp.product_id="1657" and ovtp.option_values_id=ov.id and ov.options_id=o.id and
o.name="Size" group by ovtp.id )';
Yes, this is a nagging feature of mysql and there is a workaround to it: wrap the subquery within the IN() clause into another subquery.
update option_values_to_products set available="0" where id in (select id from (
select ovtp.id from option_values ov,option_values_to_products ovtp,options o where
ovtp.product_id="1657" and ovtp.option_values_id=ov.id and ov.options_id=o.id and
o.name="Size" group by ovtp.id ) as t)
Avoid using nested queries for many reasons like performance and memory issue, also it can be very hard to be understood for the next developers
Good practice Split your query into 2 parts :
<?php
$qSelect = 'select ovtp.id from option_values ov,option_values_to_products ovtp,options o where
ovtp.product_id="1657" and ovtp.option_values_id=ov.id and ov.options_id=o.id and
o.name="Size" group by ovtp.id';
$res = DATABASE_MANAGER::exec($qSelect);
$qUpdate = 'update option_values_to_products set available="0" where id in (' . implode(",", $res) .')';
$res2 = DATABASE_MANAGER::exec($qUpdate);

Mysql Query with two tables php

I was wondering how to do a query with two tables in php?
I have this single query
?php
$sQuery = "Select * From tb_columnas Where col_Status='activo' Order by col_ID DESC";
$result = mysql_query($sQuery, $cnxMySQL) or die(mysql_error());
$rows_result = mysql_fetch_assoc($result);
$total_rows_result = mysql_num_rows($result);
if ($total_rows_result > 0){
do {
$id_columnas = $rows_result ['col_ID'];
$col_Titulo = $rows_result ['col_Titulo'];
$col_Resumen = $rows_result ['col_Resumen'];
$col_Fecha = $rows_result ['col_Fecha'];
$col_Autor = $rows_result ['col_Autor'];
?>
But I'd like to compare the col_Autor with au_Nombre which is in another table (tb_autores) and get au_Photo and other values from it, how can I do that?
You can do a simple join query without using the JOIN keyword by specifying the two tables in the FROM clause and establishing a relationship in the where clause.
For example
SELECT columns
FROM table1, table2
WHERE table1.field = table2.field
You are asking about SQL Joins, the practicing of putting two or more tables together in an SQL statement to return data from more than 1 table. You join the tables on a common column, such as author.authorid = book.authorid. I suggest looking up JOINS on google, there are many good articles.
A great article on it: http://www.sitepoint.com/understanding-sql-joins-mysql-database/
It sounds like you are looking for a join. Try something like the following:
SELECT * FROM tb_columnas JOIN tb_autores ON tb_columnas = col_Autor WHERE col_Status='activo' ORDER BY col_ID DESC
You need to understand joins for this.
Here you will find very good explanation of the same:
http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html

I can't retrieve the values from database

$raw_results=mysql_query("SELECT resort_name FROM resorts WHERE resort_id=(SELECT resort_id FROM resort_place WHERE place_id=(SELECT place_id FROM place WHERE place='$query')) ") or die(mysql_error());
$check_num_rows=mysql_num_rows($raw_results);
$solutions = array();
while($row = mysql_fetch_assoc($raw_results)) {
$solutions[] = $row['solution'];
}
This is my code and it returns an error message like
Warning: mysql_query() [function.mysql-query]: Unable to save result set in C:\xampp\htdocs\search\news.php on line 131
Subquery returns more than 1 row
can any one help me to retrieve the values from the data base...
this will yield the same result with you multiple subquery.
SELECT DISTINCT a.resort_name
FROM resorts a
INNER JOIN resort_place b
ON a.resort_id = b.resort_id
INNER JOIN place c
ON b.place_id = c.place_id
WHERE c.place='$query'
As a sidenote, the query is vulnerable with SQL Injection if the value(s) came from the outside. Please take a look at the article below to learn how to prevent from it. By using PreparedStatements you can get rid of using single quotes around values.
How to prevent SQL injection in PHP?
Use prepared statements using mysqli_ or PDO functions instead. Your query can be accomplished using an explicit JOIN:
SELECT DISTINCT resorts.resort_name
FROM resorts
JOIN resort_place ON resort_place.resort_id = resorts.resort_id
JOIN place ON place.place_id = resort_place.place_id
WHERE place.place = '$query'
use IN operator like place_id in (your sub query here)
$raw_results=mysql_query("SELECT resort_name FROM resorts WHERE resort_id IN
(SELECT resort_id FROM resort_place WHERE place_id IN
(SELECT place_id FROM place WHERE place='$query')
)
") or die(mysql_error());
The other answers are wise, you could do better than nesting queries.
If you really want to do AND my_column_id = (SELECT something FROM ...)
make sure that the subquery returns only one row, maybe by ending it with LIMIT 0, 1.

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

Categories