Cakephp 3.x order by date with different date notations - cakephp-3.0

I have a row (varchar) with date notations retreived from digital camera's.
This notation differs between types and models.
Now, I want to order this row by datetaken ASC or DESC.
->order(['Searches.datetaken' => 'DESC']);
This is not working correct with values like 20100115 and 20160302164444 (example).
To fix this, I want to use STR_TO_DATE()
But how do I use this in a correct way in Cakephp 3.x
This is not working:
->order([STR_TO_DATE(Searches.datetaken,'Ymd') => 'DESC']);

Related

How to select from a json encoded field that contains nested data?

The fields looks like this:
[{"Tester":"Bonnie","Credentials":"MS","Date":"2013-02-19"},
{"Tester":"Karen","Credentials":"Teacher","Date":"2016-01-20"}]
I need to select based on the year of the 'Date' value: < > or =
I have found the json_extract function and it's shortcuts such that this will get the data (from the MySQL docs) "autowrapped as an array" and it works:
json_field->"$[*].Date" returns ["2013-02-19", "2016-01-20"]
Great, so I has the dates from the json data, but now I need to format the WHERE. How do I select the record if either of the years is 2016 for instance? I don't see any json function that do that.
I would highly recommend you to drop this JSON column and build another table, then you can search in your table using JOIN. JSON in column is a bad idea.
Just to answer your question:
I think this should work -
WHERE YEAR(STR_TO_DATE(json_field->"$.Date", '%Y-%m-%d')) = '2016'

MySQL REGEXP Y-m-d with multiple months

I'm storing some data in a field called published. I need to use a regular expression to match the format of Y-m-d. Y and d can be excluded, however i need to any value in array of 3 months like $months = ['01,'02','03]. i need to match any of the 3 months in my regular expression this is my regex so far:
$regex = '^([0-9]{4}\-'.$months.'\-[0-9]{2})$';
I'm unsure on what the syntax would be for the months. would it be like 01|02|03? i'm not very good with regular expressions yet.
Updated
I found the following regex which will match:
^([0-9]{4}\-{1}(05|01|03){1}\-{1}[0-9]{2})$ not sure if its compatible with mysql but i'm going to try and see what happens. http://regexr.com/3c440
Why don't you just use:
WHERE MONTH(`datefield`) IN(1, 2, 3)
It's much easier to work with datetime fields, as it's easier to lookup and parse the format into a readable format MySQL can use.
Searching ranges becomes easy:
WHERE `datefield` >= '2015-01-01' AND `datefield` < '2015-04-01'
The full list of functions can be found here, and you can use functions such as STR_TO_DATE to convert to a dateformat.
#FrankerZ answer works, however for our purposes the field can store any type of text, not just a Y-m-d formatted date. This query is intended to target only records with a pattern that matches Y-m-d format and all others are simply not cared about for this exercise.
I was able to accomplish it myself with:
SELECT * FROM test WHERE published REGEXP '^([0-9]{4}\-{1}(05|01|03){1}\-{1}[0-9]{2})$'
http://sqlfiddle.com/#!2/7e311/1

MySQL BETWEEN for dates saved as string

Here's the thing - I'm saving date in database as string in format dd/mm/yyyy. I want to get rows in which date is between two dates - let's say 11/07/2009 and 29/08/2014, how to do that?
I tried
SELECT * FROM attr WHERE time_added between '11/7/2009' AND '29/8/2014'
but it's not working correctly. Any great would be great?
First of all, it is recommended to use the MySQL's DATE type for dates, selecting the date range would be easy and efficient. But if you have your own reason to use string type (like you are working with a specific calender and you don't have the converter), then you should consider followings:
you told that you are using the dd/mm/yyyy format for dates but in your code you wrote 11/7/2009 which should be 11/07/2009
In order to select range you should save your date like yyyy/mm/dd, specially when you put index on this filed, it will be high performance.
You need not to save format charterers like '/' in database. you can format the output later and show the date in any order and format you want.
As the result I offer you the following solution:
Use the YYYYMMDD format to save the date. the select query will be something like:
SELECT *, DATE_FORMAT(time_added, '%d/%m/%Y') AS time_added2 FROM attr
WHERE time_added between '20090711' AND '20140829';
As and alternative if you can not change the database, then the following query will work on the existing database (date saved in dd/mm/yyyy format):
SELECT * FROM attr WHERE
CONCAT(SUBSTR(time_added, 7, 4), SUBSTR(time_added, 4, 2), SUBSTR(time_added, 1, 2))
BETWEEN '20090711' AND '20140829';

Sorting strings with numbers and text in Rails

In my database I have table with a name column containing grades, like 1. grade, 2. grade, and so on. When the numbers have reached 10 or more, the sorting doesn't work as I would like, as 10. grade comes before 2. grade in the sorted recordset. I know this is because string sorting is different from integer sorting. The question is how to sort these strings in a numeric way.
Because the grade-records are a part of a tree buildt with the ancestry plugin, I have to put the whole sorting code inside :order => "(some code that sorts the results)".
I have tried :order => "CAST(SUBSTRING_INDEX(name, '.') AS SIGNED)". But this doesn't work.
I use SQLite in my development environment and MySQL in the production environment.
try this:
replace the constant vale '. grade' of your column with empty string, then you get the numeric value. cast the same to int
order by cast(replace(name,'. grade','') as int)
EDIT:
as per your comment if its not 'grade' always, then try
order by cast(left(name,LOCATE('.',name,1)-1) as UNSIGNED)
SQL fiddle demo

how to store a date in a mysql database?

If I have a date such as mm/dd/yyyy. How can I get mysql to actually store the date in that format. Is this possible or do have to store it in the form of yyyy/mm/dd and convert it later?
What I want to do is insert a date in the mm/dd/yyyy format but the database will not allow it. It wants yyyy/mm/dd
What is your reason for doing this? I can't see any reasonable use for it.
You cannot change the way MySQL stores dates, no. But you can of course format them when reading/writing them. You can do it in SQL query like this:
For example you can use STR_TO_DATE function to format the date when inserting it:
INSERT INTO mytable (mydate) VALUES (STR_TO_DATE('12/31/2009', '%m/%d/%Y'))
And vice versa:
SELECT DATE_FORMAT(mydate, '%m/%d/%Y') FROM mytable /* returns 12/31/2009 */
But as FactalizeR pointed out, it is not a good practice to do it in the query and it should be moved to script, like this (considering you are using PHP).
$date = '12/31/2009';
$date = date('Y-m-d', strtotime($date));
mysql_query("INSERT INTO mytable (mydate) VALUES ({$date})");
And vice versa
$date = mysql_result(mysql_query("SELECT mydate FROM mytable"), 0, 0);
$date = date('m/d/Y', strtotime($date)); //returns 12/31/2009
There is a built-in DATE type in MySQL. It allows to store a date. And later in your programming language you extract this date and convert to whatever format you like. Also, conversion can be done directly in MySQL via DATE_FORMAT(date,format) function.
MySQL DATE fields must store the date in YYYY-MM-DD (including dashes) format. If you attempt to store it any other way you will have problems with date comparisons and ordering.
Conversion later is a trivial task. Is there a compelling reason why you are trying to avoid doing this? What other technology are you using to talk to the MySQL database? (i.e. PHP, C# etc...)
I think you're mixing up what you are storing - the date itself - with how that date is subsequently referred to.
Why do you want to store in a particular format? Do you want to insert in that format? In which case you might be able to get away with it, depending on the localisation of your install, but otherwise convert - insert would be the way to do it (depending, of course, on how you're inserting).
Are you creating a SQL command from strings?