How to stop ordering CONCAT REGEXP MySQL - mysql

I have the following code which force me to order values from lowest to highest.
$values = '4|2|7|1|20';
$test = $db->QueryFetchArrayAll("SELECT id FROM user WHERE (CONCAT(',', id, ',') REGEXP ',($values),')");
foreach ($test as $test_as) {
echo $test_as['id'].',';
}
// Output:
1,2,4,7,20
// Should be same as string values:
4,2,7,1,20
How I can stop ordering it by default and make by values order?

Add a
ORDER BY FIELD(id,4,2,7,1,20);
To your SELECT.
You still should use prepared stetement when you are4 testing.

Related

How to compare Comma Seperated value to get existing value

I have Table as Production with field name as production_code
Production_code have value like this,
Id production_code
1 P101,P102,P103,P105
2 P103,P106,P102
3 P104
4 P102,P105,P111
------ I have value on PHP page like $p_code='P102,P109';
Now I want to fetch rows from Table Production_code where any code is exist in production_code of variable $p_code
please help me .. what mysql query should i use
You can use function FIND_IN_SET, like:
SELECT * FROM yourTable
WHERE FIND_IN_SET('P102', production_code) OR FIND_IN_SET('P109', production_code)
Solution.
<?php
$p_code='P102,P109'; //example
$condition = '';
foreach(explode(',',$p_code) as $r){//explode convert $p_code string into array. then apply foreach for compare every element of array From database saved value
$condition .= 'FIND_IN_SET("'.$r.'", production_code) OR ';
}
$condition = rtrim($condition,' OR '); //this remove last occurence of OR from condition
echo $sql = 'SELECT * FROM yourTable
WHERE '.$condition;
?>

Get results from WPDB

I have this scenario that I can't figure out:
Inside table wp_comment I need to list all user_id (not duplicate) with comment_type=complete.
I tried this:
$results = $GLOBALS['wpdb']->get_results( "SELECT * FROM wp_comments WHERE comment_type='sensei_course_status' AND comment_approved='complete'", ARRAY_A );
$corsisti = $results[user_id];
// I need to print only ids to put this array in
get_users( include=> '$corsisti' )
The database screenshot:
You can use the wpdb::get_col() method to retrieve an array with values from a single column:
$corsisti = $GLOBALS['wpdb']->get_col( "SELECT `user_id` FROM wp_comments WHERE comment_type='sensei_course_status' AND comment_approved='complete'");
Then simply use the result in get_users (you do not need the quotes):
$users = get_users( include=> $corsisti );

Retrieve mysql data without any order applied

I have a table with the name of actions with primary key of action_id, i am retrieving data from this table as passing my own ordered action_ids for example
$actionIds = array(5,9,10,21,3,18,4);
$actionsTb = Engine_Api::_()->getDbtable('actions','activity');
$postSelect = $actionsTb->select()
->where('action_id IN(?)', $actionIds)
->where('type = ?', 'status')
;
now the issue is when i get the result back its in ascending order, like ( 3,4,5,9,10,18,21 ) but what i want the order of result as i passed the action ids means don't want to apply any order on the result.
please help me. you can reply with simple query too.
Since your using php, why not use loop to dynamically create where clause here is the code
$where = "action_id IN(";
for($x=0; $x<count($actionIds); $x++)
{
// code for adding comma in every end of id
if($x==count($actionIds)-1)
{
// found the last data in array add closing parenthesis in IN funtion
$where.=$actionIds[$x].")";
}
else
{
$where.=$actionIds[$x].",";
}
}
to test the output echo it first
echo $where; //so i think the result is "action_id IN(5,9,10,21,3,18,4)"
Here is the complete code
$actionIds = array(5,9,10,21,3,18,4);
$where = "action_id IN(";
for($x=0; $x<count($actionIds); $x++)
{
// code for adding comma in every end of id
if($x==count($actionIds)-1)
{
$where.=$actionIds[$x].",";
}
else
{
// add closing parenthesis in IN funtion
$where.=$actionIds[$x].")";
}
}
$actionsTb = Engine_Api::_()->getDbtable('actions','activity');
$postSelect = $actionsTb->select()
->where($where)
->where('type = ?', 'status')
;
I don't know zend coding but following approach may help you.
->where( 'FIND_IN_SET( action_id, ? )', $actionIds )
I am not sure if zend's where converts the array $actionIds to be linear item values i.e. '5,9,10,21,3,18,4'. If converted, part of the resulting query would look like:
where find_in_set( action_id, '5,9,10,21,3,18,4' )
Example:
mysql> select find_in_set( 18, '5,9,10,21,3,18,4' );
+---------------------------------------+
| find_in_set( 18, '5,9,10,21,3,18,4' ) |
+---------------------------------------+
| 6 |
+---------------------------------------+
1 row in set (0.00 sec)
Reference:
Read MySQL documentation on FIND_IN_SET

Selecting all records using SQL LIMIT and OFFSET query

I wonder if there is a way to accomplish:
SELECT * FROM table
by using LIMIT and OFFSET like so:
SELECT * FROM table LIMIT all OFFSET 0
Can I write SQL statement using LIMIT and OFFSET but still getting ALL result?
* of course I can use an IF statement but I rather avoid it if possible
From the MySQL documentation:
To retrieve all rows from a certain offset up to the end of the result
set, you can use some large number for the second parameter. This
statement retrieves all rows from the 96th row to the last:
SELECT * FROM tbl LIMIT 95,18446744073709551615;
So getting all rows might look as follows:
SELECT * FROM tbl LIMIT 0,18446744073709551615;
Yes, it is possible by providing NULL:
SELECT * FROM tab LIMIT NULL OFFSET NULL
db<>fiddle PostgreSQL demo
7.6. LIMIT and OFFSET
LIMIT ALL is the same as omitting the LIMIT clause, as is LIMIT with a NULL argument.
Snowflake LIMIT / FETCH
The values NULL, empty string (''), and $$$$ are also accepted and are treated as “unlimited”; this is useful primarily for connectors and drivers (such as the JDBC driver) if they receive an incomplete parameter list when dynamically binding parameters to a statement.
SELECT * FROM demo1 ORDER BY i LIMIT NULL OFFSET NULL;
SELECT * FROM demo1 ORDER BY i LIMIT '' OFFSET '';
SELECT * FROM demo1 ORDER BY i LIMIT $$$$ OFFSET $$$$;
I used this code in nodeJS with MySQL and it's run well, It's may help you.
Why you use it?
It's reliable because it's a string that will append with query.
If you want to set limit then you can put the limitation with the variable otherwise pass 0 with variable.
var noOfGroupShow=0; //0: all, rest according to number
if (noOfGroupShow == 0) {
noOfGroupShow = '';
}
else {
noOfGroupShow = ' LIMIT 0, '+noOfGroupShow;
}
var sqlGetUser = "SELECT `user_name`,`first_name`,`last_name`,`image`,`latitude`, `longitude`,`phone`,`gender`,`country`,`status_message`,`dob` as user_date_of_birth FROM `tb_user` WHERE `user_id`=?"+noOfGroupShow;
This may not be the best way to do it, but its the first that comes to mind...
SELECT * FROM myTable LIMIT 0,1000000
Replace 1000000 with some adequately large number that you know will always be larger than the total number of records in the table.
As the record will grow up, use mysql_num_rows to dynamically find total amount of records, instead of using some large number.
$cektotalrec=mysql_query("SELECT * FROM TABLE");
$numoffset=mysql_num_rows($cektotalrec);
$numlimit="0";
then:
$final="SELECT * FROM table ".$numlimit.", ".$numoffset"";
Maybe not the cleanest solution but setting limit to a very high number could work. Offset needs to be 0.
Why not use a IF statement where you add the limit and offset to the query as a statement is true?
You might receive an error if you set the limit to a very high number as defined by mysql doc. Thereofre, you should try to limit it 9999999999999, going higher can give you an error unless you set up server to go higher.
You might want to use LIMIT in a function, therefore it is not a bad idea. If you use it in a function, you might want it to be Limit All at one point and limit 1 at another point.
Below, I list an example where you might want your application to have no limit.
function get_navigation($select = "*", $from= "pages", $visible= 1, $subject_id = 2, $order_by = "position", $sort_by = "asc", $offset=0, $limit = 9551615){
global $connection;
$query = " SELECT {$select} ";
$query .= " FROM {$from} ";
$query .= " WHERE visible = {$visible} ";
$query .= " AND subject_id = {$subject_id} ";
$query .= " ORDER BY {$order_by} {$sort_by} ";
$query .= " LIMIT {$offset}, {$limit} ";
mysqli_query($connection, $query);
$navigation_set = mysqli_query($connection, $query);
confirm_query($navigation_set);
return $navigation_set;
}
define ("SELECT", "*");
define ("FROM", "pages");
define ("VISIBLE", 1);
define ("SUBJECT_ID", 3);
define ("ORDER_BY", "position");
define ("SORT_BY", "ASC");
define ("LIMIT", "0");
$navigation_set = get_navigation(SELECT, FROM, VISIBLE, SUBJECT_ID, ORDER_BY, SORT_BY);

mySQL: get hash value for each row?

Currently I'm manually creating a string where I concatenate all the values in each row in my table. I'm hashing this string for each row to get a hash value for the current values (/status) of the row, which I'm later is using to determine if the row has changed.
Instead of doing this manually, is there an build-in way i mySQL to get a unique hash value for each row?
you could do something like
SELECT MD5(concat(field1, field2, field3, ...)) AS rowhash
but you can't get away from listing which fields you want, as concat(*) is not an option (syntax error).
It's better to use concat_ws(). e.g. two adjacent column: 12,3 => 1,23 .
Sorry, this still has some problems. Think about the null value, empty string, string can contain ',', etc...
A program is required to generate the hash statement, which should replace null to specific value (for null-able columns), and also use the seldom used char/byte as separator.
There are problems with CONCAT, e.g. CONCAT('ab', 'c') vs CONCAT('a', 'bc'). Two different rows, but result is the same. You could use CONCAT_WS(';', 'ab', 'c') to get ab;c but in case of CONCAT_WS(';', ';', '') vs CONCAT_WS(';', '', ';') you still get the same result.
Also CONCAT(NULL, 'c') returns NULL.
I think the best way is to use QUOTE:
SELECT MD5(CONCAT(QUOTE(c1), QUOTE(c2), QUOTE(c3))) AS row_hash FROM t1;
Result of: select (concat(quote('a'), quote('bc'), quote('NULL'), quote(NULL), quote('\''), quote('')));
is: 'a''bc''NULL'NULL'\''''
Also, don't use GROUP_CONCAT() to get hash of table, it has limit: https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_group_concat_max_len
Instead, CHECKSUM TABLE might be better, but you can't skip columns with CHECKSUM TABLE https://dev.mysql.com/doc/refman/5.7/en/checksum-table.html
Well I made a little script that could do excactly what you want, and maybe what others want... so here it goes...for PHP that is...
first you have to make a list of columns of the table, then you make a "case when" statement for each column based on their type and put that in the concat_ws statement and then you hash it with sha1...i've used this method on very large tables (600000+ records) and the speed is quite good when selecting all records. also I think that it is faster to concat the required data in a concat_ws and explode it in php or whatever you are using, but that is just a hunch...
<?
$query= mysql_query("SHOW COLUMNS FROM $table", $linklive);
while ($col = mysql_fetch_assoc($query)) {
$columns[] = mysql_real_escape_string($col['Field']);
if ($col['Key'] == 'PRI') {
$key = mysql_real_escape_string($col['Field']);
}
$columnsinfo[$col['Field']] = $col;
}
$dates = array("date","datetime","time");
$int = array("int","decimal");
$implcols = array();
foreach($columns as $col){
if(in_array($columnsinfo[$col]['Type'], $dates)){
$implcols[] = "(CASE WHEN (UNIX_TIMESTAMP(`$col`)=0 || `$col` IS NULL) THEN '[$col EMPTY]' ELSE `$col` END)";
}else{
list($type, $rest) = explode("(",$columnsinfo[$col]['Type']);
if(in_array($columnsinfo[$col]['Type'], $dates)){
$implcols[] = "(CASE WHEN ( `$col`=0 || `$col` IS NULL ) THEN '[$col EMPTY]' ELSE `$col` END)";
}else{
$implcols[] = "(CASE WHEN ( `$col`='' || `$col` IS NULL ) THEN '[$col EMPTY]' ELSE `$col` END)";
}
}
}
$keyslive = array();
//echo "SELECT $key SHA1(CONCAT_WS('',".implode(",", $columns).")) as compare FROM $table"; exit;
$q = "SELECT $key as `key`, SHA1(CONCAT_WS('',".implode(", ",$implcols).")) as compare FROM $table";
?>