I have a script in PHP, which selects data from a Mysql Database using Select & Where clause.
$lrn= "PU2017LN11K";
$stmt = $user_home->runQuery('SELECT * FROM mcq WHERE LRN = :crn ORDER BY LRN,Sr ASC ');
$stmt->bindParam(':crn',$lrn);
$stmt->execute();
Now how to script the code so that it selects from all the LRN, using WHERE LRN = :crn.
I tried:
$lrn= "*";
$stmt = $user_home->runQuery('SELECT * FROM mcq WHERE LRN = :crn ORDER BY LRN,Sr ASC ');
$stmt->bindParam(':crn',$lrn);
$stmt->execute();
But it didn't show any results!
It's easy to skip the WHERE clause if I want to show all results, but
the value of $lrn will be defined by the $_GET method.
The normal way of handling this would be:
$lrn= "*";
$stmt = $user_home->runQuery('SELECT * FROM mcq WHERE LRN = :crn OR :crn = \'*\' ORDER BY LRN, Sr ASC ');
Alternatively, you could use LIKE:
$lrn = "%";
$stmt = $user_home->runQuery('SELECT * FROM mcq WHERE LRN LIKE :crn ORDER BY LRN, Sr ASC ');
You want all rows, don't use a where clause. Alternatively, if you must use a where (something in your code or thinking/design requires it), then you can also say something like "where 1" (like the way phpMyAdmin does things all the time, for what ever reason).
Use this as your where clause:
WHERE LRN = CASE WHEN :crn = '*' THEN LRN else :crn END
That way when the supplied :crn is '*' you will get all records.
Related
The following is the PHP code I am using for a simple search feature in my website.
The search simply shows refults if it matches the SQL column "tags".
I would like to add one more filter in the SQL query.
I want to filter the search results based on city.
The city data is already in the SQL, but I dont know how to add it here without breaking the properly working search funtion.
I tried $data_sql .= " AND city='newyork' "; after the 8th line, but it didnt work.
$name=str_replace(' ', '%', $_POST['query']);
$newsearch = "%$name%";
$base_sql = "SELECT %s FROM posts WHERE tags LIKE ?";
$count_sql = sprintf($base_sql, "count(*)");
$stmt = $connect->prepare($count_sql);
$stmt->execute([$newsearch]);
$total_data = $stmt->fetchColumn();
$data_sql = $count_sql = sprintf($base_sql, "*")." LIMIT ?,?";
$stmt = $connect->prepare($data_sql);
$stmt->execute([$newsearch, $start, $limit]);
$result = $stmt->fetchAll();
So your additional filter must be before LIMIT ?, ?
if you try adding it after the 8th line the query will look like this:
SELECT * FROM posts WHERE tags LIKE 'search' LIMIT 0, 100 AND city='newyork'
so what can you do:
$data_sql = sprintf($base_sql, "*");//we will add the limit before preparation
//don't know why do you need that $count_sql here
$data_sql .= " AND city='newyork' ";
//IF you need some GROUP BY do it here
//If you need some ORDER BY do it here
$data_sql .= " LIMIT ?, ?";
$stmt = $connect->prepare($data_sql);
$stmt->execute([$newsearch, $start, $limit]);
$result = $stmt->fetchAll();
The line $data_sql .= " AND city='newyork' "; won't work as it will add the string after the LIMIT which is not a valid sql query.
You should instead edit the line with the base_sql like this:
$base_sql = "SELECT %s FROM posts WHERE tags LIKE ? AND city='newyork'";
And of course if 'newyork' needs to be a variable you can do thr same thing like you did for the tags
First, let's add the new criteria:
$base_sql = "SELECT %s FROM posts WHERE tags LIKE ? and city = ?";
Then make sure that you pass the city as a parameter
$stmt->execute([$newsearch, 'newyork', $start, $limit]);
Ok so I have two Tables
Applicant list - this shows all applicants
User Table
Now I'm Providing news_id by Post method and I want to list details of all users(email,mobile,username) where the value for user_authToken and user_authtoken is same. Can Someone help me out with this logic using PHP.
$job_id = $_POST['job_id'];
$resultSet = $con->query("SELECT appliers_list.news_id AS jobid ,
appliers_list.user_authToken AS user,
user.user_name AS username,
user.mobile AS mobile,
FROM appliers_list,user
WHERE appliers_list.news_id = '$job_id'
ORDER BY appliers_list.id DESC
");
$rows = $resultSet->fetch_assoc();
First of all, your naming is very inconsistent, it's hard to read and understand.
Second, please use prepare statement, otherwise you open your system to SQL injection.
$news_id = $_POST['job_id'];
$stmt = $con->prepare("SELECT email, mobile, user_name
FROM users
WHERE user_authtoken in (select user_authToken from appliers_list where news_id = ?)");
$stmt->bind_param("i", $news_id);
$stmt->execute();
$resultSet = $stmt->get_result();
while($row = $resultSet->fetch_assoc()) {
// data manipulation here
}
you can use left join to get record from both table :
$job_id = !empty($_POST['job_id']) ? intval($_POST['job_id']) : 0;
$resultSet = $con->query("SELECT appliers_list.*,users.email
FROM appliers_list
left join users on appliers_list.user_authToken = users.user_authToken
WHERE news.news_id = '$job_id'
ORDER BY news.id DESC
");
$rows = $resultSet->fetch_assoc();
You didn't specify a relationship between the user and appliers_list tables, so you're getting all rows in user. You also have an extra comma at the end of the SELECT list.
$job_id = $_POST['job_id'];
$resultSet = $con->query("SELECT appliers_list.news_id AS jobid ,
appliers_list.user_authToken AS user,
user.user_name AS username,
user.mobile AS mobile
FROM appliers_list
JOIN user ON appliers_list.user_authToken = user.user_authToken
WHERE appliers_list.news_id = '$job_id'
ORDER BY appliers_list.id DESC
");
$rows = $resultSet->fetch_assoc();
I am new to PHP PDO and trying to use named placeholder at the place of ORDER BY ASC. Sometime in simple query page this run very successfully but unable to run in the following query:
PHP CODE IS:
$price_sort = "ASC";
$keyword = "samsung glaxy";
$limit = 0;
$query = $db->prepare("SELECT *, MATCH(title) against (:keyword) as 'relevence'
FROM view_store_items_grid
WHERE MATCH(title) against(:keyword)
ORDER BY relevence DESC, price :order
LIMIT :limit,25");
$query->bindValue(":keyword",$keyword);
$query->bindValue(":order",$price_sort);
$query->bindValue(":limit", $limit, PDO::PARAM_INT);
$query->execute();
When I remove placeholder :order with ASC this run and gives result but when I use this placeholder, I get empty result.
For Fetching data or to show fetched result I am using
while ($row = $query->fetch(PDO::FETCH_ASSOC)) :
extract($row);
echo "$name";
endwhile;
What I am doing wrong and How I can use many named placeholder in query at different places?
You should not bind ASC/DESC in prepared statement. Parameters are automatically quoted, and ASC/DESC shouldn't be quoted. this is the same reason that table and column names can't be parameters.
Instead you can do like that
$sql_query = "SELECT *, MATCH(title) against (:keyword) as 'relevence'
FROM view_store_items_grid
WHERE MATCH(title) against(:keyword)
ORDER BY relevence DESC, price "
if($price_order == 'ASC'){
$sql_query .= " ASC "
}else{
$sql_query .= " DESC "
}
$sql_query .= " LIMIT :limit,25 "
$query = $db->prepare($sql_query);
Refer How bindValue in LIMIT
Refer pdo binding asc/desc order dynamically
Also do not try to use the same named parameter twice in a single SQL statement, for example
<?php
$sql = 'SELECT * FROM some_table WHERE some_value > :value OR some_value < :value';
$stmt = $dbh->prepare($sql);
$stmt->execute( array( ':value' => 3 ) );
?>
...this will return no rows and no error -- you must use each parameter once and only once. Apparently this is expected behavior (according to this bug report: http://bugs.php.net/bug.php?id=33886) because of portability issues.
This one solved this question by replacing the price_sort variable value with price ASC and removing the price before the placehoder :order
as:
$price_sort = "price ASC";
and the query is as:
$query = $db->prepare("SELECT *, MATCH(title) against (:keyword) as 'relevence'
FROM view_store_items_grid
WHERE MATCH(title) against(:keyword)
ORDER BY relevence DESC, :order
LIMIT :limit,25");
this solved my question with the help of answer of #tamil
Thank you
I'm not sure exactly how to explain what the query does, however the problem isn't entirely with how it's set up, because it does work, in another instance, when I use it as an array, however it's not working when I use it with mysql_fetch_assoc(), so here is what my original query is(not the one im having trouble with):
SELECT * FROM
(SELECT * FROM comments
WHERE postID='$id' AND state='0'
ORDER BY id DESC LIMIT 3
) t ORDER BY id ASC
what this does is selects the last 3 comments on a post, then orders them in another way (so they show up in the correct order, old to new) Now this is the query for echoing out the array of comments directly.
But now what I want to do, is to just get the first id out of the 3 comments.
here's what I have tried to do (and by the way, this query DOES work, when i replace my previous query to echo out the results in an array, but i need to get just the id for use, i don't want an array):
$previousIDq = mysql_fetch_assoc(mysql_query("
SELECT * FROM
(SELECT * FROM comments
WHERE postID='$id' AND state='0'
ORDER BY id DESC LIMIT 3
) t ORDER BY id ASC LIMIT 1"));
$previousID = $previousIDq['id']; //this doesn't return the id as I want it to.
Your problem may be that there are no matching rows.
Also, I think you could also improve your query to this:
SELECT * FROM comments WHERE postID='$id' AND state='0' ORDER BY id DESC LIMIT 2,1
But as others say, use PDO or MySQLi, and with prepared statements. And don't SELECT * ever.
try a var_dump($previousID) to see what you get
It is probably giving you back an object, and you need to get your id from that object
You script is too condensened for error handling, let alone debugging
$mysql = mysql_connect(...
$query = "
SELECT * FROM
(SELECT * FROM comments
WHERE postID='$id' AND state='0'
ORDER BY id DESC LIMIT 3
) t ORDER BY id ASC LIMIT 1
";
$result = mysql_query($query, $mysql);
if ( !$result ) { // query failed
die('<pre>'.htmlspecialchars(mysql_error($mysql)).'</pre><pre>'.htmlspecialchars($query).'</pre>');
}
$previousIDq = mysql_fetch_assoc($result);
if ( !$previousIDq ) {
die('empty result set');
}
else {
$previousID = $previousIDq['id'];
}
You need to separate your code to be able to debug
$query = "SELECT * FROM
(SELECT * FROM comments
WHERE postID='$id' AND state='0'
ORDER BY id DESC LIMIT 3
) t ORDER BY id ASC LIMIT 1";
$result = mysql_query($query);
echo mysql_error(); //what eror comes out here
while($previousIDq = mysql_fetch_assoc($result))
{
print ($previousIDq['id']);
}
NOTE: mysql_* is depreciated, upgrade to mysqli or PDO
Please stop using mysql_ functions to write new code, it is being deprecated. Use mysqli_ or PDO functions (mysqli below).
Bind your parameters to prevent SQL injection
Always use a column list (don't use SELECT *)
If you're returning > 1 row, use a while loop
mysqli_ solution
$link = mysqli_connect("localhost", "user_name", "password", "stock");
if (mysqli_connect_error()) {
die('Connect Error (' . mysqli_connect_errno() . ') ' . mysqli_connect_error());
}
$stmt = mysqli_prepare($link, "SELECT t.id FROM
(SELECT id FROM comments
WHERE postID = ? AND state = 0
ORDER BY id DESC
LIMIT 3) t
ORDER BY id ASC");
mysqli_bind_param($stmt, 's', $id) or die(mysqli_error($dbh));
$result = mysqli_stmt_execute($stmt) or die(mysqli_error($link));
while($row = mysqli_fetch_assoc($result)) {
echo $row[id];
}
mysqli_close($link);
mysql_ solution
$stmt = "SELECT t.id FROM
(SELECT id FROM comments
WHERE postID = $id AND state = 0
ORDER BY id DESC
LIMIT 3) t
ORDER BY id ASC";
$result = mysql_query($stmt) or die(mysql_error());
$row = mysql_fetch_assoc($result);
while($row = mysql_fetch_assoc($result)) {
echo $row[id];
}
I'm trying to sort data by different fields ascending and descending. But I have different mysql pdo statements for the 4 fields I have (8 queries total):
$stmt1 = $po->prepare("SELECT * FROM tabname WHERE categ=:categ ORDER BY field1 DESC");
$stmt2 = $po->prepare("SELECT * FROM tabname WHERE categ=:categ ORDER BY field1 ASC");
$stmt3 = $po->prepare("SELECT * FROM tabname WHERE categ=:categ ORDER BY field2 DESC");
$stmt4 = $po->prepare("SELECT * FROM tabname WHERE categ=:categ ORDER BY field3 ASC");
$stmt5 = $po->prepare("SELECT * FROM tabname WHERE categ=:categ ORDER BY field3 DESC");
$stmt6 = $po->prepare("SELECT * FROM tabname WHERE categ=:categ ORDER BY field3 ASC");
$stmt7 = $po->prepare("SELECT * FROM tabname WHERE categ=:categ ORDER BY field4 DESC");
$stmt8 = $po->prepare("SELECT * FROM tabname WHERE categ=:categ ORDER BY field4 ASC");
Based on input, I pick the right statement and bind and execute it.
if ($sortcode == 1){
$stmt1->bindParam(':categ', $categ, PDO::PARAM_STR);
$stmt1->execute();
$fetched = $stmt1->fetchAll(PDO::FETCH_ASSOC);
} else if ($sortcode == 2){
$stmt2->bindParam(':categ', $categ, PDO::PARAM_STR);
$stmt2->execute();
$fetched = $stmt2->fetchAll(PDO::FETCH_ASSOC);
} else if ($sortcode == 3){
$stmt3->bindParam(':categ', $categ, PDO::PARAM_STR);
$stmt3->execute();
$fetched = $stmt3->fetchAll(PDO::FETCH_ASSOC);
}
//repeat the block 5 more times, for a total of 8
This doesn't look right at all. Since the select statements only differ int he name of the field and the desc/asc, is there a better way to get the $sortcode and compact the code that follows?
I guess I could state the question more specifically as: is there a way I could have a single statement/single pdo statement that binds the field name and asc/decs dynamically?
Use associative arrays to hold the prepared statements.
Your input is a column and a sorting method, right? So prepare the queries by:
$columns = array("field1", "field2", "field3", "field4");
$orders = array("asc", "desc");
$queries = array();
foreach($columns as $col) {
$queries[$column] = array();
foreach ($orders as $order) {
$queries[$column][$order] = $po->prepare("SELECT * FROM tabname WHERE categ=:categ ORDER BY $column $order");
}
}
Now, to look up the correct query, you don't need some synthetic code -- you just look it up by column and order directly.
To look up a query, instead of having your users input a number from 1-8, have them input a column and an order. Imagine that the column is in the variable $col and the order is in $ord. Just say $queries[$col][$ord].
If for some reason you have to use the number (why?), then you need a slightly different strategy. In that case, you store the queries by that number.
$columns = array("field1", "field2", "field3", "field4");
$orders = array("asc", "desc");
$queries = array();
$i = 0;
foreach($columns as $col) {
foreach ($orders as $order) {
$i = $i + 1;
$queries[$i] = $po->prepare("SELECT * FROM tabname WHERE categ=:categ ORDER BY $column $order");
}
}
In other words, you ought to be storing queries according to how you plan to look them up.
You can order by column number, which can be parameterized. Using an ORDER BY in this fashion is usually clearer if you specify the columns in the select clause. I'm not sure if ASC/DESC can be parameterized, though...
You can always build the queries dynamically. Store the map between $sortcode and the columns, the SELECT * FROM tabname WHERE categ=:categ part of the query, get the right column name based on $sortcode and add the ORDER BY ... part.