Database sorted by a specific string then random - php

Is there any way to order a database by a specific name stored in a function then random?
For example, if $name = 'Hasan' then I want the query to select Hasan row first then the other rows randomly
<?php
/* DATA BASE
id | Name
--------------+--------------------------------
'1' | Hasan
'2' | Ahmad
'3' | Majid
'4' | Hazem
*/
if(isset($_GET['name'])) {
$name = $_GET['name'];
}
else {
$name = 0;
}
$query = mysqli_query($con, "SELECT * FROM database ORDER BY $name, rand()");
?>

You can make a test on the name in the ORDER BY clause, sorting by whether it matches or not. You should use a prepared statement to protect yourself from SQL injection. For example:
$stmt = $con->prepare('SELECT * FROM database ORDER BY Name = ? DESC, rand()');
$stmt->bind_param('s', $_GET['name']);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
// ... do something
}
This works because MySQL treats boolean expressions as 0 (false) or 1 (true) in a numeric context, so the value of Name = $name will be 1 when the name matches and 0 otherwise, which you can then sort on descending.
Note that mysqli_stmt::get_result is only available with the mysqlnd native driver installed. Without that, you will need to use mysqli_stmt::bind_result, mysqli_stmt::store_result and mysqli_stmt::fetch to get your data.

You should be using a prepared statement here, something along these lines:
SELECT *
FROM database
ORDER BY name != ?;
Assuming you bound Hasan to the ? placeholder, this would give:
SELECT *
FROM database
ORDER BY name != 'Hasan';
This would place all Hasan records first (since false evaluates to 0), with all non Hasan records appearing after that. Note that your second sort level RAND() may not even be necessary, since MySQL does not guarantee any further default sorting order.

Related

SQL Use array and use result in select(sum) statement

I am trying to use the selected id's as an array a other statement. It seems it is not counting all the result as it is much lower that it is.. I have tried to find my answer on google but none of the options are working for me or i do not know how to use them in my case. There are no errors and i have error log on!
Here is my code, what am i doing wrong?
$counttheid = array();
$stmt3 = $mysqli->prepare("SELECT
id
FROM account
WHERE level <= '5' AND door = ? AND `group_name` = ? AND betaald = 'Yes'");
$stmt3->bind_param("ss",$usernamesession,$groupname);
$stmt3->execute();
$result3 = $stmt3->get_result(); //only works when nd_mysli is set on the server!
while ($rowid = $result3->fetch_assoc())
{
$counttheid[] = $rowid['id'];
$countid = implode(',', $counttheid);
}
$sql = "SELECT SUM(mobcash) AS totalcash FROM account WHERE id IN (?)
";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("s",$countid);
$stmt->execute();
$stmt->bind_result($row['totalcash']);
while($stmt->fetch()) $sumcash = $row['totalcash'];
//echo print_r($counttheid);
//echo implode(',', $counttheid);
echo $sumcash;
I am no profesional developer just started learning this, any help is welcome!
Since you have edited the question, my original answer is no longer relevant.
I suggest for you to simplify your two queries into a single query. In your first query you select a bunch of ids and in the second query you sum a different value from the same table using the ids. You can just to that in one query:
SELECT SUM(mobcash) AS totalcash
FROM account
WHERE level <= '5'
AND door = ?
AND `group_name` = ?
AND betaald = 'Yes';
Original answer
You use $result->fetch_all(MYSQLI_ASSOC), meaning each row from the result set will be an associative array with the column names as the keys and the cell values as values. That is also the case, if you only select one column.
That means for this example table
id | name | balance
----+------+---------
1 | acc1 | 12.34
2 | acc2 | 1.23
your variable $dataid will have the following value (for the simplified query SELECT id FROM account):
$dataid = [
[
"id": 1
],
[
"id": 2
]
];
To get more familiar with PHP, you could write some foreach loops yourself, but you can also use the built-in PHP function array_column (php.net: array_column):
$ids = array_column($dataids, "id");
From an SQL perspective I would also suggest for you to learn about nested queries, since you could avoid this PHP logic altogether.

Find value in column of MySQL table and print return

I have table cars and inside I have two fields year and chat_id
I have two records inside:
2019 | 1234
2018 | 1111
How can I search inside table chat_id == 1234 and return 1 if exist else 0?
How can I print this?
I tried this but doesn't work:
$chat_id= 1234;
$query= "SELECT IF(chat_id == $chat_id,0,1) AS return FROM cars";
$return_id= mysqli_query($connection, $query);
print_r($return_id);
To check for existence you do not need to select any data from the DB. You can just fetch 1 if it exists otherwise it will return NULL. Also you should always remember to use prepared statements and never inject PHP variables into SQL queries.
$chat_id = 1234;
$stmt = $connection->prepare('SELECT 1 FROM cars WHERE chat_id = ?');
$stmt->bind_param('i', $chat_id);
$stmt->execute();
// fetch the first column from the first row as an integer
$return_id = (int) $stmt->get_result()->fetch_row()[0];
Another option is to use bind_result as can be seen in this article: How to check whether a value exists in a database using mysqli prepared statements
You can use mysqli_num_rows to check if the record exists and WHERE clause to filter the results.
$chat_id= 1234;
$query= "SELECT chat_id FROM cars WHRE chat_id = '$chat_id'";
$return_id= mysqli_query($connection, $query);
$rowcount = mysqli_num_rows($return_id);
echo $rowcount; // Will return total number of rows matched else will return zero

How To Rank Rows in Descending Order Based on Chosen Column Values And Get Presented Only Qualified Rows?

Imagine my Mysql Tbl looks like this:
Item|Score
cam|2
car|5
window|1
glass|4
Now, I want php mysqli to present rows who's values (in the score column) are greater than "1". From our example, I want it presented like this:
Item|Score
car|5
glass|4
cam|2
NOTE: The row "window|1" has not been presented since it's value in the score column is not greater than "1".
Question 1: Is there a simple way to achieve my purpose without any Groupings done on the Mysql query ? If so, how ?
What would be the Mysql query and what would the php code (Prepared Statements) be when using the Mysqli extension ?
I do not think the following are accurate. Hence, I need your professional inputs.
1st ATTEMPT:
$score = >1;
$query = "SELECT item, score FROM tbl WHERE score = ? ORDER by score DESC";
$stmt = mysqli_prepare($conn,$query);
mysqli_stmt_bind_param($stmt,'i',$score);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_bind_result($stmt,$item, $db_score);
mysqli_stmt_fetch($stmt);
mysqli_stmt_free_result($stmt);
2nd ATTEMPT:
$score = >1;
$query = "SELECT item, score FROM tbl WHERE score > ? ORDER by score DESC";
$stmt = mysqli_prepare($conn,$query);
mysqli_stmt_bind_param($stmt,'i',$score);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_bind_result($stmt,$item, $db_score);
mysqli_stmt_fetch($stmt);
mysqli_stmt_free_result($stmt);

use result of mysql query into a new query

I have this mysql table.
name | total
chris | 5
jan | 3
bob | 2
eric | 4
chris and jan were selected using this code
$query = " select * from table where name = '$given_name' ";
// &given_name = result from another query
I want to store the result of the query to a variable.
while($row=mysql_fetch_assoc($query)){
$result = $row['name'];
} // i want to store both chris and jan to $result
Then i will use the result of the query to another query. I want to select the remaining names. Not the ones on the first query. I want chris and jan not to be selected with this query because it is stored in $result
select * from table where name != $result ;
But one name was just stored in $result. I want them both to be stored in $result.
You could use FIND_IN_SET to see if the names had been fetched before. Firstly you need to make $result an array of all the names:
$result = array();
while ($row=mysql_fetch_assoc($query)) {
$result[] = $row['name'];
}
Then you can write your query to exclude the names in $result:
$sql = "SELECT * FROM table WHERE NOT FIND_IN_SET(name, '" . implode(',', $result) . "')";
You can use database query like below to exclude chris and jan:
select * from table where name NOT IN( $result );
Assuming that you do not know the names of the resultset you can simply (a) select the first two names from the resultset, (b) concatenate them in a string and finally (c) use "NOT IN" as your query parameter.
$numPicks = 2; // decide how many names you want in the list
// OR if you want to exclude ALL names found in the first query
$num_rows = mysql_num_rows($query);
$nameList = ''; // start with an empty string
for($i=0; $i<$numPicks; $i++) { // then use $num_rows here instead of numPicks
$nameList .= $row['name'].',';
}
$nameList = rtrim($nameList,','); // remove trailing comma from the string
$sql = "select * from table where name NOT IN ($nameList)";

mysql like statement is not working as expected

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.

Categories