Table :
Value:
gte
2016-06-07
aze
2015-07-08
(...)
Important :
Value stores Varchar (because it can be a string, a number, a date etc...)
I need to "sort by" the value that look like a date
Something that i imagine like this ?
ORDER BY (value LIKE "%Y-%m-%d") DESC
If the date is formatted as you describe as YYYY-MM-DD, you just need to remove the - separator. It is then sortable as a string into numeric order.
Try something like
SELECT *
FROM Table
ORDER BY REPLACE(Value,'-','') DESC
if you try to convert it to date you will get null for other none date values
example
mysql> mysql> select STR_TO_DATE('5/15/2012 8:06:26 AM','%c/%e/%Y %r');
+---------------------------------------------------+
| STR_TO_DATE('5/15/2012 8:06:26 AM','%c/%e/%Y %r') |
+---------------------------------------------------+
| 2012-05-15 08:06:26 |
+---------------------------------------------------+
1 row in set (0.00 sec)
mysql> select STR_TO_DATE('dfsddfs','%c/%e/%Y %r');
+--------------------------------------+
| STR_TO_DATE('dfsddfs','%c/%e/%Y %r') |
+--------------------------------------+
| NULL |
+--------------------------------------+
1 row in set, 1 warning (0.00 sec)
1st try to convert it to date and get not null results and the sort using ORDER BY
SELECT * FROM (SELECT STR_TO_DATE(value, "%Y-%e-%c") AS DT FROM TABLE) T WHERE T.DT IS NOT NULL ORDER BY DT;
This should order a recordset by placing all the "date-looking" values at the top. It uses a RegEx pattern in the "LIKE" clause:
SELECT * FROM (
SELECT VALUE,
case when VALUE LIKE '[0-9]{4}-[0-9]{2}-[0-9]{2}' then 1 else 0 END AS LOOKS_LIKE_DATE
FROM TABLE
) ORDER BY LOOKS_LIKE_DATE DESC
Related
I am trying to get the date part from a timestamp field.
I used this SQL query:
select timestamp, CAST(timestamp as date) as date from messages
I got the following result:
--------------------------------------------
| timestamp | date |
--------------------------------------------
| 2016-05-15 10:22:54 | 2016-05-16 |
--------------------------------------------
As shown above, the date field produced returns the wrong date 2016-05-16 whereas the original date is 2016-05-15.
How can we resolve this issue?
Thats not a issue !!! Its only set the wrong time_zone. see sample
get current time_zone
SHOW GLOBAL VARIABLES LIKE 'time_zone'; -- systemwide setting
SHOW VARIABLES LIKE 'time_zone'; -- session setting
sample
MariaDB [mysql]> select t, CAST(t as date) FROM groupme LIMIT 1;
+---------------------+-----------------+
| t | CAST(t as date) |
+---------------------+-----------------+
| 2016-05-15 20:22:54 | 2016-05-15 |
+---------------------+-----------------+
1 row in set (0.00 sec)
MariaDB [mysql]> SET time_zone ='-12:00';
Query OK, 0 rows affected (0.00 sec)
MariaDB [mysql]> select t, CAST(t as date) FROM groupme LIMIT 1;
+---------------------+-----------------+
| t | CAST(t as date) |
+---------------------+-----------------+
| 2016-05-14 20:22:54 | 2016-05-14 |
+---------------------+-----------------+
1 row in set (0.00 sec)
MariaDB [mysql]>
Use date not cast because is not casting but a format
select timestamp, date(timestamp) as my_date from messages
I would suggest you to use the DATE_FORMAT function and not the CAST since you are formatting the date like
SELECT `timestamp`, DATE_FORMAT(`timestamp`, '%Y-%m-%d) as my_date from messages
Also note that both CAST and DATE function internally call Item_date_typecast function so there is no such difference between them.
Try this
select timestamp, cast(timestamp as date format 'yyyymmddhhmmss') as date from messages
I have mysql table with multiple columns, a column has string data type namely code and the values of the column might be digits only or mixed of string and digits e.g: one row value has 57677 and other rows column value like 2cskjf893 or 78732sdjfh.
mysql> select * from testuser;
+------+--------------+
| id | code |
+------+--------------+
| 1 | 232 |
| 2 | adfksa121dfk |
| 3 | 12sdf |
| 4 | dasd231 |
| 5 | 897 |
+------+--------------+
5 rows in set (0.00 sec)
mysql> show create table testuser;
+----------+------------------------------------------------------------------ ---------------------------------------------------------------+
| Table | Create Table |
+----------+------------------------------------------------------------------ ---------------------------------------------------------------+
| testuser | CREATE TABLE `testuser` (
`id` int(11) DEFAULT NULL,
`code` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+----------+------------------------------------------------------------------ ---------------------------------------------------------------+
1 row in set (0.00 sec)
mysql>
I would like to filter out only rows which has numeric value in code column or filter rows which has string values in code column.
try this
Mysql Query to fetch only integer values from a particular column
SELECT column FROM TABLE where column NOT REGEXP '^[0-9]+$' ;
Mysql Query to fetch only string values from a particular column
SELECT column FROM TABLE where column REGEXP '^[0-9]+$' ;
To get digits
SELECT id,code
FROM table_name
WHERE code REGEXP '^[0-9]+$';
To get string values
SELECT *
FROM table_name
WHERE code REGEXP '^[a-zA-Z]+$'
Use regular expressions
SELECT *
FROM myTable
WHERE code REGEXP '^[0-9]+$';
This will filter out column values with all digits.
You can use regular expressions in mysql too.
SELECT * FROM `table` WHERE `code` REGEXP '[0-9]';
Results will be the rows, where any number in the code column.
Try this,
select id,code from table_name where code NOT REGEXP '^[0-9]+$'
Or,
select id,code from table_name where code like '%[^0-9]%'
Here's my MySQL query:
SELECT YEARWEEK(paid) AS yweek,
STR_TO_DATE(YEARWEEK(paid), '%X%V') AS date,
COUNT(*) AS cnt
FROM members
WHERE YEARWEEK(paid) >= YEARWEEK(curdate()) - 52
GROUP BY yweek
Here is the result:
yweek date cnt
201429 0000-00-00 201
201430 0000-00-00 435
201431 0000-00-00 333
201432 0000-00-00 470
201433 0000-00-00 534
The yweek column and cnt column are fine, but the date column is always 0000-00-00. The paid column in the members table is of the format (PHP) date("Y-m-d H:i:s"), is of the column type TIMESTAMP, and here's an example: 2014-06-26 00:32:02.
I have tried replacing YEARWEEK(paid) with CAST(YEARWEEK(paid) AS CHAR(7)), but that changes nothing.
Does the fact that I'm using a TIMESTAMP cause STR_TO_DATE() to give all zeros? I want to have the first date of the week along with cnt, the number of registrations in that week.
Problem is: you cannot get a date from a yearweek: there's 7 options, which one do you want?
mysql> SELECT STR_TO_DATE('201429', '%X%V');
+-------------------------------+
| STR_TO_DATE('201429', '%X%V') |
+-------------------------------+
| 0000-00-00 |
+-------------------------------+
1 row in set (0.00 sec)
If we add a 'day of the week' (%w) to it, it magically begins to worK:
mysql> SELECT STR_TO_DATE('2014290', '%X%V%w');
+----------------------------------+
| STR_TO_DATE('2014290', '%X%V%w') |
+----------------------------------+
| 2014-07-20 |
+----------------------------------+
1 row in set (0.00 sec)
But: this means you have to choose the day of the week you want statically, because the original date is no longer in a yearweek.
Of course, in this case, you might as well have done this:
SELECT
YEARWEEK(paid) AS yweek,
DATE(paid) AS date,
COUNT(*) AS cnt
....
... but I assumed this was just an illustration of the problem getting a date of a yearweek string. If not, then this second solution will just work for you.
In one of my tables I have a column which is varchar(255). The where clause looks like this
SELECT ….. WHERE ctd_ref != 0.
Well this works fine if the value is an integer greater than zero but does not select the entries which have ctd_ref value = N8IJVW
What I'm doing wrong?
If you cast strings to zero, you get zero almost all the times, and even when you don't I don't think you get the results you want:
mysql> select cast('abc' as decimal), cast('' as decimal), cast('7zip' as decimal);
+------------------------+---------------------+-------------------------+
| cast('abc' as decimal) | cast('' as decimal) | cast('7zip' as decimal) |
+------------------------+---------------------+-------------------------+
| 0 | 0 | 7 |
+------------------------+---------------------+-------------------------+
1 row in set, 2 warnings (0.00 sec)
Just don't force such conversions, which I suspect you never intended to do:
SELECT … WHERE ctd_ref <> '0'
... and also try the opposite clause for debugging purposes:
SELECT … WHERE ctd_ref = '0'
If it's a varchar try WHERE ctd_ref != '0'
If you leave it as 0, you're comparing a number to a string field, which will give you, as you say, weird results.
I'm running into a problem, I have the following line in my query
CONCAT('',
(SELECT GROUP_CONCAT(DISTINCT trips_loads_rel.load_id,'') AS x
FROM `trips_loads_rel` WHERE trips_loads_rel.trip_id = trips.Id)
) AS loads
It shows something like 8,10,27 (ie, numeric IDs), some Ids from trips_loads_rel table. It works ok. However, how can I use that output to pull matching records from other table? I mean, the line shows me all ids ok, but I need to query other table with these to pull related records. Actually I don't need these IDs, I need their matching records...
try this:
SELECT * FROM <other_table> WHERE <other_table>.load_id IN(CONCAT('',
(SELECT GROUP_CONCAT(DISTINCT trips_loads_rel.load_id,'') AS x
FROM `trips_loads_rel` WHERE trips_loads_rel.trip_id = trips.Id)
) AS loads)
It looks like it's a part of a query, not an entire one, so hard to show exact syntax, but if you want to use the values to find other rows, just don't group concat them to begin with.
Instead just use them directly doing something like;
SELECT * FROM `other_table` WHERE `other_table`.`load_id` IN
(SELECT `load_id` FROM `trips_loads_rel` WHERE `trip_id` = `trips`.`Id`)
You can use FIND_IN_SET(col, 'csv as string') function to get the desired results.
Example:
mysql> select find_in_set( 2, '11,12,13,14,15,2' );
+--------------------------------------+
| find_in_set( 2, '11,12,13,14,15,2' ) |
+--------------------------------------+
| 6 |
+--------------------------------------+
1 row in set (0.00 sec)
mysql> select find_in_set( 2, '2,11,12,13,14,15,2' );
+----------------------------------------+
| find_in_set( 2, '2,11,12,13,14,15,2' ) |
+----------------------------------------+
| 1 |
+----------------------------------------+
1 row in set (0.00 sec)
mysql> Select FIND_IN_SET( 6, '1,12,3,14,5,16,7,18,9,0,2,13,4,15,6,17,8' );
+--------------------------------------------------------------+
| FIND_IN_SET( 6, '1,12,3,14,5,16,7,18,9,0,2,13,4,15,6,17,8' ) |
+--------------------------------------------------------------+
| 15 |
+--------------------------------------------------------------+
1 row in set (0.00 sec)
mysql>
For your query you can pass the concatenated output '8,10,27' to compare with other_table's column.
Select find_in_set( other_table.col_name, '8,10,27' );
Refer To:
MySQL String Functions: FIND_IN_SET()