How to use REGEXP in MYSQL to match dates IN array? - php

I am trying to match the year from the publication_date of a table in a lot of years. I am using laravel (PHP).
I have written something like:
if($this->request->has('publication_years')){
$years = implode('-[0-9]{2}-[0-9]{2}|', explode(',', $this->request->get('publication_years'))) . '-[0-9]{2}-[0-9]{2}';
$model = $model->whereExists(function ($query) use ($years)
{
$query->select(DB::raw(1))
->from('patent')
->whereRaw('patent.id = document.documentable_id')
->whereRaw('document.documentable_type = "patent"')
->whereRaw('(patent.publication_date REGEXP (' . $years . '))');
});
}
The years come like ?publication_years=2015,2016. I explode them use the , delimiter and then implode them to make the REGEXP pattern in a way it matches the date. The dump of the years after this is like 2015-[0-9]{2}-[0-9]{2}|2016-[0-9]{2}-[0-9]{2}.
This works at http://regexr.com/ but I am still getting error so I am guessing there some other syntax for MYSQL. The error that I see is:
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '[0-9]{2}-[0-9]{2}|2016-[0-9]{2}-[0-9]{2})))' at line 1 (SQL: select count(*) as aggregate from `document` where exists (select * from `folder` where `document`.`folder_id` = `folder`.`id` and (exists (select * from `user` inner join `accessible_by_user` on `user`.`id` = `accessible_by_user`.`user_id` where `accessible_by_user`.`accessible_id` = `folder`.`id` and `accessible_by_user`.`accessible_type` = folder and `user_id` = 1) or exists (select * from `role` inner join `accessible_by_role` on `role`.`id` = `accessible_by_role`.`role_id` where `accessible_by_role`.`accessible_id` = `folder`.`id` and `accessible_by_role`.`accessible_type` = folder and `role_id` in (1)))) and exists (select 1 from `patent` where patent.id = document.documentable_id and document.documentable_type = "patent" and (patent.publication_date REGEXP (2015-[0-9]{2}-[0-9]{2}|2016-[0-9]{2}-[0-9]{2}))))
What am I doing wrong? How can I correct this?

Here is a way to prep the regex for using in MySQL:
$this_request_get_publication_years = "2015,2016,2017";
$years = '^(' . implode('|', explode(',',
$this_request_get_publication_years)) . ')-[0-9]{2}-[0-9]{2}';
echo "(patent.publication_date REGEXP '" . $years . "')";
// => (patent.publication_date REGEXP '^(2015|2016|2017)-[0-9]{2}-[0-9]{2}')
The REGEXP '^(2015|2016|2017)-[0-9]{2}-[0-9]{2}' will only fetch the records that:
^ - at the start of the string, have...
(2015|2016|2017) - either of the 3 years (and more are supported, surely)
-[0-9]{2} - a hyphen followed with 2 digits
-[0-9]{2} - ibid.
The latter two subpatterns can be shrunk into (-[0-9]{2}){2}.

Related

Select from table where clause from array from another table

I'm trying to insert a failsafe into a code to prevent them from going a step further, and I've been scratching my head for a while now. I am able to put something into an array, but I am not able to get the items from the array to match the second select query. I only get Array instead of the value from the item.
My first select query is this:
$datohenter3 = "select DATE_FORMAT(datotid, '%Y.%m.%d') AS dato from gramorapport34 group by dato order by dato asc";
$hentdatoer = $db->query($datohenter3);
$periodedatoer = array();
for ($x = 1; $x <= $db->affected_rows; $x++) {
$periodedatoer[] = $hentdatoer->fetch_assoc();
}
Then I want to match the values from this array with my next select query:
$rapportdatoer = "select fradato, tildato from gramorapportlogg WHERE fradato IN('".$periodedatoer."') OR tildato IN('".$periodedatoer."')";
$rapportdatoeksist = $db->query($rapportdatoer);
if ( !$rapporteksist ) die('Database Error: '.$db->error);
while($row = mysqli_fetch_array($rapportdatoeksist))
{
print_r($row);
}
The errors I am getting are:
Notice: Array to string conversion for the second select
Database Error: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ' fradato IN('Array') OR tildato IN('Array')' at line 1
I'm not an expert in JOIN SELECT queries. This is using MariaDB 10.3.12 with PHP7.2
var_dump available at: https://www.lokalradio.no/rapport/gramo/datohenttest.php
Notice that $periodedatoer is an array of array. Each element inside has 1 key of dato (as you var_dump displays).
So use array-column to get the values and then implode as:
$rapportdato = implode("','", array_column($periodedatoer, "dato"));
Now you can use $rapportdato in your second query as:
$rapportdatoer = "select fradato, tildato from gramorapportlogg WHERE fradato IN('" . $rapportdato . "') OR tildato IN('" . $rapportdato . "')";

What is wrong with this SQL syntax in Laravel?

This query uses $hotel_id, and two date variables to get some data from database. But I keep receiving this error:
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax
This is a piece of bigger query used in another project, and works perfectly there. But has some problems in my project that I can't figure out.
The $from_Date and $to_Date variables are alright.
What is wrong with this MySQL statement?
$splitDate = explode('/', $start);
$from_Date = jalali_to_gregorian($splitDate[0], $splitDate[1], $splitDate[2], 1);
$splitDate = explode('/', $end);
$to_Date = jalali_to_gregorian($splitDate[0], $splitDate[1], $splitDate[2], 1);
$query = DB::statement('SELECT DISTINCT t.type_id pmrtypeid ,(CASE WHEN COUNT(t.type_id)-qb.cntrttypid IS Null THEN COUNT(t.type_id) ELSE COUNT(t.type_id)-qb.cntrttypid END)cnttypeid FROM type t JOIN room r
on r.type_id=t.type_id
LEFT JOIN (SELECT DISTINCT rt.type_id rttypid,COUNT(rt.type_id)cntrttypid FROM reserve_type rt
JOIN reserve re
ON re.reserve_id=rt.reserve_id
JOIN type ty
ON ty.type_id=rt.type_id
WHERE ((? BETWEEN re.from_date AND re.to_date) or (? BETWEEN re.from_date AND re.to_date)) AND ty.hotel_id=?
GROUP BY rt.type_id)qb
ON qb.rttypid=t.type_id
JOIN reserve_span rsn
ON rsn.hotel_id=t.hotel_id
WHERE r.hotel_id=? AND ((? BETWEEN rsn.from_date AND rsn.to_date) and (? BETWEEN rsn.from_date AND rsn.to_date)) and rsn.is_enable=1
GROUP BY t.type_id)pmr
on pmr.pmrtypeid=tps.type_id
join type_feture tf
on tps.type_id=tf.type_id' , [$from_Date,$to_Date,$hotel_id,$hotel_id,$from_Date,$to_Date] );
}
The problem came out to be an extra piece of the other code in mine:
)pmr
on pmr.pmrtypeid=tps.type_id
join type_feture tf
on tps.type_id=tf.type_id
The useless parentheses created an error. I also changed DB::statement() into DB::select() as suggested by #Erubiel.
Why are you using DB::statement() instead of DB::select()?
Also, DB::statement() does not take the binding values array parameter.
https://laracasts.com/discuss/channels/laravel/l5-bindings-is-not-working-with-dbstatement

Query 2 tables join

I want to get all the films whose genre is equal to ID_GENRE = 8. This is the query that I'm doing:
http://l4c.me/fullsize/2-tablas-1434140362.png
$query_GetSimilar = sprintf("SELECT * FROM z_movie,z_movie_genre ORDER BY z_movie.visits DESC WHERE z_movie_genre.id_genre = 8 LIMIT 18");
$GetSimilar = mysql_query($query_GetSimilar, conect::dbconect()) or die(mysql_error());
$row_GetSimilar = mysql_fetch_assoc($GetSimilar);
$totalRows_GetSimilar = mysql_num_rows($GetSimilar);
But I jump the next error
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE z_movie_genre.id_genre = 8 LIMIT 18' at line 1
Note:
WHERE should be first before ORDER BY
You can use INNER JOIN to get two connecting tables, assuming that they have connecting id/column.
For example, both z_movie and z_movie_genre table has the column id_genre to connect each other, you can try this:
$query_GetSimilar = sprintf("SELECT * FROM z_movie
INNER JOIN z_movie_genre ON z_movie.id_genre = z_movie_genre.id_genre
WHERE z_movie_genre.id_genre = 8
ORDER BY z_movie.visits DESC
LIMIT 18");
Make a simple search, and see if you can put 'order by' before 'where'.
ok, now my query is:
$query_GetSimilar = sprintf("SELECT * FROM z_movie,z_movie_genre WHERE z_movie_genre.id_genre=8 ORDER BY z_movie.visits DESC LIMIT 18");
$GetSimilar = mysql_query($query_GetSimilar, conect::dbconect()) or die(mysql_error());
$row_GetSimilar = mysql_fetch_assoc($GetSimilar);
$totalRows_GetSimilar = mysql_num_rows($GetSimilar);
but I do not have the expected results

MySQL query can't handle variables

I'm trying to query to my database, but for some reason the query is only working when I enter the parameters hard coded. If I use variables, the query refuses to work...
This is my query with hard coded parameters and works just fine:
$q_jobs = 'select distinct nid from node n, field_data_field_job_tags as tags
where (type= \'job\' and n.language = \'nl\' and tags.entity_id = n.nid
and tags.field_job_tags_value = \'Enterprise Asset Management\')
order by n.changed desc limit 7';
But when I use variables, the query refuses to work...
$q_jobs = 'select distinct nid from node n, field_data_field_job_tags as tags
where (type= \'job\' and n.language = :lang and tags.entity_id = n.nid
and tags.field_job_tags_value = :title)
order by n.changed desc limit 7';
$results_jobs = db_query($q_jobs, array(':lang' => $language->language,
':title' => $node->title));
Although it's a Drupal query, I assume it's just an error somewhere in my syntax?
I get this error:
PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error
in your SQL syntax; check the manual that corresponds to your MySQL server version for
the right syntax to use near '(type= 'job' and n.language = 'nl' and tags.entity_id =
n.nid and tags.field_job' at line 1: select distinct nid from {node} n,
field_data_field_job_tags as tagswhere (type= 'job' and n.language = :lang and
tags.entity_id = n.nid and tags.field_job_tags_value = :title)order by
n.changed desc limit 7; Array ( [:lang] => nl [:title] => Enterprise
Asset Management ) in rd_get_related_news_and_blogs()
You have a typo here: field_data_field_job_tags as tagswhere (type= - there should be a space between tags and where so the quoted part of Your SQL should be field_data_field_job_tags as tags where (type=.
Always read all of the mysql error message - the query it is failing with is always quoted thus You can easily find any typo or other mistake in Your query.
EDIT: cos You don't believe me, here is repeated query from the mysql error message:
select distinct nid from {node} n, field_data_field_job_tags as tagswhere (type= 'job' and n.language = :lang and tags.entity_id = n.nid and tags.field_job_tags_value = :title)order by n.changed desc limit 7;
Now see where You have a newline in Your query and where should be (and is not) a space within the query MySQL returned as failing.
Then put a space at the end of every line and see that the query is working...
I will help You, there should be space between tags and where and between \'Enterprise Asset Management\') and order by - but it is NOT. The only space is between n.nid and and tags.field_job_tags_value because of the tab space...

Setting an error limit while updating table based conditions php

I have got a question. I have not done this before and am not sure if that is how it should be done.
I have a mySQL query which is working correctly. I use it in phpMyAdmin query editor whenever I want to do an update. However, I want to make life easier for a user by putting the query in a php script so the user can just click a link and the task is done.
I did the following:
$sql = " SET #error_limit = 10E-6;
UPDATE (
SELECT r.rmc_id, 'rmc_raw_data' src, r.rmc_time, r.rmc_date, r.latitude, r.longitude,
IF(s.server_id IS NULL, 'Mobile', 'Both') c FROM rmc_raw_data r
LEFT JOIN server_log_data s
ON r.rmc_time = s.server_rmc_time AND r.rmc_date = s.server_rmc_date AND ABS(r.latitude - s.server_latitude)/r.latitude < #error_limit AND ABS(r.longitude - s.server_longitude)/r.longitude < #error_limit
UNION
SELECT s.server_id, 'server_log_data' src, s.server_rmc_time, s.server_rmc_date, s.server_latitude, s.server_longitude, IF(r.rmc_id IS NULL, 'Server', 'Both') c FROM rmc_raw_data r
RIGHT JOIN server_log_data s
ON r.rmc_time = s.server_rmc_time AND r.rmc_date = s.server_rmc_date AND ABS(r.latitude - s.server_latitude)/r.latitude < #error_limit AND ABS(r.longitude - s.server_longitude)/r.longitude < #error_limit
) t
LEFT JOIN rmc_raw_data r1
ON r1.rmc_id = t.rmc_id AND t.src = 'rmc_raw_data'
LEFT JOIN server_log_data s1
ON s1.server_id = t.rmc_id AND t.src = 'server_log_data'
SET
r1.data_source = c, s1.data_source = c;";
$result = mysql_query($sql, $link);
if($result){
echo " Query executed successfully";
...
...
So I put the whole thing my php script but got a mysql error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UPDATE ( SELECT r.rmc_id, 'rmc_raw_data' src, r.rmc_time, r.rmc_date, r.latit' at line 1
Could someone suggest what am doing wrong here? It is my thinking that the error limit I have set on the first line of the query is responsible but I had thought that one could put his working query in the mysql_query() and it works.
'rmc_raw_data' src, this quotes will break the query ???

Categories