So what I'd really like to do is combine the two queries.
I broke them up into two to help me figure out where the issue is.
sql2 is where the issue is. When I run it in phpMyAdmin (without WHERE)it works so what's going on here?
$holidayID = formval('holidayID');
$sort= formval('sort', 'rating');
$dir = formval('dir', 'ASC');
$sql = "SELECT recipeID, holidayID, recipeName, rating
FROM recipes
WHERE holidayID = $holidayID
ORDER BY $sort $dir ";
//execute
$result = mysqli_query($dbc, $sql);
$sql2 = "SELECT recipes.holidayID, holidays.holidayName
FROM recipes
JOIN holidays ON recipes.holidayID=holidays.holidayID
WHERE holidayID = $holidayID
LIMIT 1";
$result2 = mysqli_query($dbc, $sql2);
var_dump($result2);
The first query works fine.
So what am I doing wrong?
Thank you for your time.
The problem with your query is that the holidayID in your WHERE condition is ambiguous - MySQL doesn't know if you mean from the recipes or holidays table. Specify it, like you do when selecting and joining,
SELECT recipes.holidayID, holidays.holidayName
FROM recipes
JOIN holidays ON recipes.holidayID=holidays.holidayID
WHERE holidays.holidayID = $holidayID -- Specify the column, here its holidays
LIMIT 1
You should also note that this query might be vulnerable to SQL injection, and that you should utilize prepared statements in order to protect your database against that.
How can I prevent SQL injection in PHP?
Using proper error-reporting, with mysqli_error($dbc);, MySQL would've told you this as well.
PHP.net on mysqli_error();
Related
There are many questions on SO about this but I cannot find one that quite meets my situation.
I want to use the values in some fields/columns of a table to set the value of a third field/column
In other words something like:
table races
athleteid|difficulty|score|adjustedscore
$sqlSelect = "SELECT athleteid,difficulty,score FROM races";
$res = mysql_query($sqlSelect) or die(mysql_error());
while ($row = mysql_fetch_array($res)){
$adjustedscore=difficulty*score;
$sqlupdate = "UPDATE race, set adjustedscore = '$adjustedscore' WHERE athletes = 'athletes'";
$resupdate = mysql_query($sqlupdate);
}
My understanding, however, is that MYSQL does not support update queries nested in select ones.
Note, I have simplified this slightly. I am actually calculating the score based on a lot of other variables as well--and may join some tables to get other inputs--but this is the basic principal.
Thanks for any suggestions
You can run:
UPDATE `races`
SET `adjustedscore` = `difficulty` * `score`
WHERE `athleteid` IN (1, 2, 3, ...)
First of all, as previous commentators said, you should use PDO instead of mysql_* queries.
Read about PDO here.
When you'll get data from DB with your SELECT query, you'll get array. I recommend you to use fetchAll() from PDO documentation.
So, your goal is to save this data in some variable. Like you did with $row.
After that you'll need to loop over each array and get your data:
foreach($row as $r) {
//We do this to access each of ours athlete data
$adjustedscore= $row[$r]["difficulty"]* $row[$r]["score"];
//Next row is not clear for me...
$query = "UPDATE race SET adjustedscore = '$adjustedscore' WHERE athletes = 'athletes'";
And to update we use PDO update prepared statement
$stmt = $dbh->prepare($query);
$stmt->execute();
}
How to select results from table where cat = '$cat' and if it's not equal then select all from cat no matter what $cat is.
Here is my query
$sql = mysql_query("SELECT * FROM `obiavi` WHERE `postdate`+`days`*86400 > $time AND `town` IN ('$oblasti') AND `desc` LIKE '%$keyword%' ORDER BY id DESC LIMIT $start, $perpage") or die (mysql_error());
From my understanding, you want only results where cat = '$cat'. If you obtain no results, then you want to have results no matter what their cat is.
This cannot be done effectively in a single query, you need to use two queries.
If your first query with the condition returns no results, then you attempt the second query, without the cat condition.
Best practices
Consider defending yourself against MySQL Injections
Also, please consider using MySQLi or PDO instead of MySQL.
Part of my page I have lots of small little queries, probably about 6 altogether, grabbing data from different tables. As an example:
$sql_result = mysql_query("SELECT * FROM votes WHERE voted_on='$p_id' AND vote=1", $db);
$votes_up = mysql_num_rows($sql_result);
$sql_result = mysql_query("SELECT * FROM votes WHERE voted_on='$p_id' AND vote=0", $db);
$votes_down = mysql_num_rows($sql_result);
$sql_result = mysql_query("SELECT * FROM kids WHERE (mother_id='$p_id' OR father_id='$p_id')", $db);
$kids = mysql_num_rows($sql_result);
Would it be better if these were all grabbed in one query to save trips to the database? One query is better than 6 isn't it?
Would it be some kind of JOIN or UNION?
Its not about number of queries but amount of useful datas you transfer. If you are running database on localhost, is better to let sql engine to solve queries instead computing results in additional programs. The same if you are thinking about who should be more bussy. Apache or mysql :)
Of course you can use some conditions:
SELECT catName,
SUM(IF(titles.langID=1, 1, 0)) AS english,
SUM(IF(titles.langID=2, 1, 0)) AS deutsch,
SUM(IF(titles.langID=3, 1, 0)) AS svensk,
SUM(IF(titles.langID=4, 1, 0)) AS norsk,
COUNT(*)
FROM titles, categories, languages
WHERE titles.catID = categories.catID
AND titles.langID = languages.
example used from MYSQL Bible :)
If you really want to lower the number of queries, you can put the first two together like this:
$sql_result = mysql_query("SELECT * FROM votes WHERE voted_on='$p_id'", $db);
while ($row = mysql_fetch_array($sql_result))
{
extract($row);
if ($vote=='0') ++$votes_up; else ++$votes_down;
}
The idea of joining tables is that these tables are expected to have something in between (a relation, for example).
Same is for the UNION SELECTS, which are prefered to be avoided.
If you want your solution to be clean and scalable in future, I suggest you to use mysqli, instead of mysql module of PHP.
Refer to: mysqli::multi_query. There is OOP variant, where you create mysqli object and call the function as method.
Then, your query should look like:
// I use ; as the default separator of queries, but it might be different in your case.
// The above could be set with sql statement: DELIMITER ;
$query = "
SELECT * FROM votes WHERE voted_on='$p_id' AND vote=1;
SELECT * FROM votes WHERE voted_on='$p_id' AND vote=0;
SELECT * FROM kids WHERE (mother_id='$p_id' OR father_id='$p_id');
";
$results = mysqli_multi_query($db, $query); // Returns an array of results
Fewer queries are (generally, not always) better, but it's also about keeping your code clear enough that others can understand the query. For example, in the code you provided, keep the first two together, and leave the last one separate.
$sql_result = mysql_query("SELECT vote, COUNT(*) AS vote_count
FROM votes
WHERE voted_on='$p_id'
GROUP BY vote", $db);
The above will return to you two rows, each containing the vote value (0 or 1) and the vote count for the value.
I have written some code to update certain rows of a table with a decreasing sequence of numbers. To select the correct rows I have to JOIN two tables. The last row in the table needs to have a value of 0, the second last -1 and so on. To achieve this I use ORDER BY DESC. Unfortunately my code brings up the following error:
Incorrect usage of UPDATE and ORDER BY
My reading suggests that I can't use UPDATE, JOIN and ORDER BY together. I've read that maybe subqueries might help? I don't really have any idea how to change my code to do this. Perhaps someone could post a modified version that will work?
while($row = mysql_fetch_array( $result )) {
$products_id = $row['products_id'];
$products_stock_attributes = $row['products_stock_attributes'];
mysql_query("SET #i = 0");
$result2 = mysql_query("UPDATE orders_products op, orders ord
SET op.stock_when_purchased = (#i:=(#i - op.products_quantity))
WHERE op.orders_id = ord.orders_id
AND op.products_id = '$products_id'
AND op.products_stock_attributes = '$products_stock_attributes'
AND op.stock_when_purchased < 0
AND ord.orders_status = 2
ORDER BY orders_products_id DESC")
or die(mysql_error());
}
Just remove your ORDER BY in your UPDATE statement, then put it in your SELECT statement.
sample:
$query = "SELECT ........ ORDER BY ..."
$result = mysql_query($query);
while(....){.... }
UPDATE statement wont accept ORDER BY clause.
You could use a SELECT call to loop through the rows, and include your WHERE and ORDER BY statements there, and then within your while($row = mysql_fetch_assoc($query)){ loop you'd have your UPDATE table SET key = 'value' WHERE id = '{$row['id']}' statement.
Sure, this would require executing mysql_query() a lot, but it'll still run pretty fast, just not at the same speed a single query would.
Why do you need an order by in an update. I think you could just remove it and you update will update everything that respect your where statement.
EDIT: And maybe you could call a stored proc to simplify your code
I have a table with 4 record.
Records: 1) arup Sarma
2) Mitali Sarma
3) Nisha
4) haren Sarma
And I used the below SQL statement to get records from a search box.
$sql = "SELECT id,name FROM ".user_table." WHERE name LIKE '%$q' LIMIT 5";
But this retrieve all records from the table. Even if I type a non-existence word (eg.: hgasd or anything), it shows all the 4 record above. Where is the problem ? plz any advice..
This is my full code:
$q = ucwords(addslashes($_POST['q']));
$sql = "SELECT id,name FROM ".user_table." WHERE name LIKE '%".$q."' LIMIT 5";
$rsd = mysql_query($sql);
Your query is fine. Your problem is that $q does not have any value or you are appending the value incorrectly to your query, so you are effectively doing:
"SELECT id,name FROM ".user_table." WHERE name LIKE '%' LIMIT 5";
Use the following code to
A - Prevent SQL-injection
B - Prevent like with an empty $q
//$q = ucwords(addslashes($_POST['q']));
//Addslashes does not work to prevent SQL-injection!
$q = mysql_real_escape_string($_POST['q']);
if (isset($q)) {
$sql = "SELECT id,name FROM user_table WHERE name LIKE '%$q'
ORDER BY id DESC
LIMIT 5 OFFSET 0";
$result = mysql_query($sql);
while ($row = mysql_fetch_row($result)) {
echo "id: ".htmlentities($row['id']);
echo "name: ".htmlentities($row['name']);
}
} else { //$q is empty, handle the error }
A few comments on the code.
If you are not using PDO, but mysql instead, only mysql_real_escape_string will protect you from SQL-injection, nothing else will.
Always surround any $vars you inject into the code with single ' quotes. If you don't the escaping will not work and syntax error will hit you.
You can test an var with isset to see if it's filled.
Why are you concatenating the tablename? Just put the name of the table in the string as usual.
If you only select a few rows, you really need an order by clause so the outcome will not be random, here I've order the newest id, assuming id is an auto_increment field, newer id's will represent newer users.
If you echo data from the database, you need to escape that using htmlentities to prevent XSS security holes.
In mysql, like operator use '$' regex to represent end of any string.. and '%' is for beginning.. so any string will fall under this regex, that's why it returms all records.
Please refer to http://dev.mysql.com/doc/refman/5.0/en/pattern-matching.html once. Hope, this will help you.