$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.
Related
I want to retrieve og tags with sql in php language but I only get to see 1 result, that is the first one he reads, the other I don't get to see in page source.
this is the code with php.
$query = "SELECT metatitle FROM isacontent_content WHERE contentid = 12245
UNION ALL
SELECT name FROM isacontent_module_anchorimage WHERE contentid = 12245";
$resimage = $conn->query($query);
if(is_array($resimage)){
foreach ($resimage as $resItem){
$metaData[] = $resItem->fetch_assoc();
}
}else{
$metaData[] = $resimage->fetch_assoc();
}
$title = $metaData[0]["metatitle"];
$image = $metaData[0]["name"];
I expect that both select statements will work and I can see both contents in the meta tags
For UNION ALL, your column name must be same or you can use ALIAS for this.
but, here in your example, you can simply use INNER JOIN to get the both values from 2 tables by using 1 single query.
Example:
SELECT ic.metatitle, im.name FROM isacontent_content ic
INNER JOIN isacontent_module_anchorimage im ON im.contentid = ic.contentid
WHERE ic.contentid = 12245
Using INNER JOIN because your both tables having relation, so you can simply use INNER JOIN
Side Note:
If you know, your query will return 1 row then why are you storing data into an array here $metaData[]? you can simply store $title and $image inside you foreach() loop.
When you use union, your columns have to be in same number as it will combine results of two queries. In your case your asking for an particular content results which are stored in multiple tables, so you can go for joins.
I have 4 tables in database and an unique clientid is common in all tables but rest field are different. if we search for any client id , how can we get the information stored corresponding to the searched client id from the any table.
$clientid=$_POST['client'];
$query = "SELECT * FROM 'pfs'
JOIN 'pfssurety'
JOIN 'iso'
JOIN 'incometax'
WHERE clientid='$clientid'";
$result = mysql_query($query)or die (mysql_error());
while($row=mysql_fetch_array($result)) {
echo $row['clientid'];
echo $row['name'];
}
Here is an implementation using mysqli and prevents injection for your $clientid where the id is a number grate then zero as AUTO_INCREMENT columns will never have a 0 value they start at 1
// as this is an int using inval will force it to be a valid whole number
// basic SQL Injection Protection for a fixed id
$clientid = intval($_POST['client']);
if($clientid === 0){
// it was not a valid number as an auto_increment field in mysql can never be 0
die("invalid client");
}
$query="SELECT * FROM `pfs`
JOIN `pfssurety` ON pfssurety.clientid = pfs.clientid
JOIN `iso` ON iso.clientid = pfs.clientid
JOIN `incometax` ON incometax.clientid = pfs.clientid
WHERE pfs.clientid=$clientid";
$result= mysqi_query($query) or die("Query Failed");
while($row=mysql_fetch_array($result))
{
echo $row['clientid'];
echo $row['name'];
}
You meant to use backtique instead of single quote. Otherwise your table names are considered as normal string literal. Also, you are missing ON condition for all your JOIN clauses So your query
SELECT * FROM 'pfs'
Should actually be
SELECT * FROM `pfs`
Change your query to be
SELECT * FROM `pfs`
JOIN `pfssurety` ON condition
JOIN `iso` ON condition
JOIN `incometax` ON condition
WHERE clientid='$clientid'
Maybe you need to set the on in your join as something like this:
SELECT * FROM 'pfs'
JOIN 'pfssurety' ON pfs.clientid=pfssurety.clientid
JOIN 'iso' ON pfs.clientid=iso.clientid
JOIN 'incometax' ON pfs.clientid=incometax.clientid
WHERE clientid='$clientid'
Y suposed that all tables have the clientid attribute.
Instead of using the SELECT * you could use the enumeration of the different attributes you need
You are on the right track using JOIN. You need to specify the common column that the JOIN should be made on.
https://www.w3schools.com/sql/sql_join_left.asp
SELECT a.fieldname, i.fieldname, t.fieldname, p.fieldname FROM 'pfs' as a
LEFT JOIN 'pfssurety' as p ON p.clientid = a.clientid
LEFT JOIN 'iso' as i ON i.clientid = a.clientid
LFT JOIN 'incometax' as t ON t.clientid = a.clientid
WHERE a.clientid='$clientid'";
Also, you should escape your variables to prevent SQL Injection. At a minimum:
a.clientid= "' . mysqli_real_escape_string($clientid) . '"';
http://php.net/manual/en/mysqli.real-escape-string.php
Your code is vulnerable to SQL Injection, you should never use user input directly into your SQL queries. In your code the problem is here:
$clientid = $_POST['client']; // anyone could manipulate this field to inject malicious code
# ...
WHERE clientid='$clientid'";
Check what happens if the value for $_POST['client'] is: ' or 1 = 1;
Next as mentioned in one of the comments stop using deprecated methods, instead for example you can use mysqli. Here is an example of how to use mysqli with prepared statements to avoid SQL Injection:
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$stmt = $conn->prepare('SELECT * FROM `pfs` JOIN `pfssurety` ON condition JOIN `iso` ON condition JOIN `incometax` ON condition WHERE clientid = ?');
$stmt->bind_param('i', $clientid);
$stmt->execute();
$stmt->close();
$conn->close();
A prepared statement is a feature used to execute the same (or similar) SQL statements repeatedly with high efficiency.
Compared to executing SQL statements directly, prepared statements have three main advantages:
Prepared statements reduces parsing time as the preparation on the query is done only once (although the statement is executed multiple times)
Bound parameters minimize bandwidth to the server as you need send only the parameters each time, and not the whole query
Prepared statements are very useful against SQL injections, because parameter values, which are transmitted later using a different protocol, need not be correctly escaped. If the original statement template is not derived from external input, SQL injection cannot occur.
Finally one more thing worth mentioning, try not using * to fetch all columns, instead simply list the columns you need to get. Even if you need to get all columns there are good reasons why not to use *, but instead list all columns.
I have a query with a few subqueries like so
SELECT ...
FROM (SELECT ...
FROM ...
GROUP BY ...) as speedLimitCalc INNER JOIN
(SELECT ...
FROM date a INNER JOIN HOURLY_TEST b ON a.[FULL_DAY_DT] = b.DATE
WHERE (b.DATE BETWEEN '".$date_s."' AND '".$date_e."')
AND HOUR BETWEEN ".$time_s." AND ".$time_e."
AND(LKNO BETWEEN '".$lkno_s."' and '".$lkno_e."')
AND RDNO= '".$rdno."'
AND pub_hol IN (".$pubholquery.")
AND school_hol IN (".$schholquery.")
AND day_no IN (".$dayquery.")
GROUP BY RDNO, LKNO, PRESCRIBED_DIRECTION, CWAY_CODE) as origtable ON ...
,(SELECT ...
FROM [Dim_date]
WHERE (FULL_DAY_DT BETWEEN '".$date_s."' AND '".$date_e."')
AND pub_hol IN (".$pubholquery.")
AND school_hol IN (".$schholquery.")
AND day_no IN (".$dayquery.") ) as c
ORDER BY ...
where I am inserting variables in the inner query where clause.
I am trying to parametrize this query using odbc_prepare and odbc_execute, however I am running into issues of binding the variables. At present, when I use the following
$result = odbc_prepare($connection, $query);
odbc_execute($result)or die(odbc_error($connection));
to run this query, everything works fine. However, when I try to bind a variable, such as
AND RDNO= ?
...
odbc_execute($result, array($rdno))or die(odbc_error($connection));
I get the following error message.
PHP Warning: odbc_execute() [/phpmanual/function.odbc-execute.html]: SQL error: [Microsoft][ODBC SQL Server Driver]Invalid parameter number, SQL state S1093 in SQLDescribeParameter
My guess is that it's because I'm binding a variable in a subquery, since this procedure works when the Where clause is in the top Select query.
I was wondering whether anyone else has encountered this issue before, and how they solved it? Thanks
Fixed the issue by removing the need for parameters in the subquery by separating the query into multiple queries using temporary tables.
$query = "SELECT ...
INTO ##avgspeedperlink
FROM Date a INNER JOIN HOURLY_TEST ON a.[FULL_DAY_DT] = b.DATE
WHERE (b.DATE BETWEEN ? AND ?)
AND HOUR BETWEEN ? AND ?
AND(LKNO BETWEEN ? and ?)
AND RDNO= ?
AND pub_hol IN (".$pubholquery.")
AND school_hol IN (".$schholquery.")
AND day_no IN (?,?,?,?,?,?,?)
GROUP BY RDNO, LKNO, PRESCRIBED_DIRECTION, CWAY_CODE";
$result = odbc_prepare($connection, $query);
odbc_execute($result, array($date_s,$date_e,$time_s,$time_e,$lkno_s,$lkno_e,$rdno,$daysanitised[0],$daysanitised[1],$daysanitised[2],$daysanitised[3],$daysanitised[4],$daysanitised[5],$daysanitised[6]))or die(odbc_error($connection));
$query = "SELECT ...
INTO ##daysinperiod
FROM [RISSxplr].[dbo].[Dim_date]
WHERE (FULL_DAY_DT BETWEEN ? AND ?)
AND pub_hol IN (".$pubholquery.")
AND school_hol IN (".$schholquery.")
AND day_no IN (?,?,?,?,?,?,?)";
$result = odbc_prepare($connection, $query);
odbc_execute($result, array($date_s,$date_e,$daysanitised[0],$daysanitised[1],$daysanitised[2],$daysanitised[3],$daysanitised[4],$daysanitised[5],$daysanitised[6]))or die(odbc_error($connection));
$query = "SELECT ...
FROM ##avgspeedperlink, ##daysinperiod
ORDER BY LKNO, OUTBOUND
drop table ##avgspeedperlink
drop table ##daysinperiod";
Note that I had to use double ## for making the temporary tables (single # means that table is local to the query, ## means that the temporary table becomes global for multiple queries).
This is my code:
$sql = $_POST['sql'];
....
$result = $mysqli->query($sql);
This does not return any results. So i echoed the $sql variable and this is the result:
SELECT o.entity_id, o.increment_id FROM sales_flat_order o JOIN sales_flat_order_payment p ON o.entity_id = p.parent_id JOIN sales_flat_order_address a ON o.entity_id = a.parent_id WHERE a.country_id = \'DE\' ORDER BY o.entity_id DESC LIMIT 10;
Now, when I assign this to the $sql variable directly, it works. What could be the problem?
Thanks
Well, first you could test $result and output the last error with $mysqli->error when it's false, that would give you details on what's wrong.
Secondly, you should NOT execute a query that's coming from POST or GET parameter, that's how you allow anyone to do anything on your database with sql injection. That's a big security breach.
Thirdly, the issue is probably on POST encoding (note the quotes \'DE\') so if you urldecode and/or stripslashes your $sql it would probably work
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`