I have a VARCHAR field in mysql with dates separated by commas. Like this:
"10/20/2011,10/21/2011,10/22/2011"
I need to use a WHERE condition like this:
where `date` > '10/10/2011'
So my question is basically how can i use (maybe) regex to retrieve the first date in my field (I only need the first) and apply the where condition to it?
This will get only the first part, before the comma , :
SUBSTRING_INDEX( varcharField, ',' , 1)
You then need to convert it into date format:
STR_TO_DATE( SUBSTRING_INDEX(varcharField, ',', 1), '%m/%d/%Y')
As you have already been told, storing a comma delimited list is a bad idea. But many times it's not within your job duties or abilities to restructure a table.
I think you should look up doing full-text indexes and matching. This will allow for searching within a field. Sadly only available on MyISAM tables.
Related
I have a table, one of the columns contains a text values, some of which are comma separated string, like this:
Downtown, Market District, Warehouse District
I need to modify my query to see is a given value matches this column. I decided that using IN() is the best choice.
SELECT *
FROM t1
WHERE myValue IN (t1.nighborhood)
I am getting spotty results - sometimes I return records and sometimes not. If there's a value in t1.nighborhood that matches myValue, I do get data.
I checked and there are no MySQL errors. What am I missing?
You can use FIND_IN_SET() to search a comma-delimited list:
SELECT *
FROM t1
WHERE FIND_IN_SET(myValue, REPLACE(t1.nighborhood, ', ', ','));
The REPLACE() is necessary to remove the extra spaces.
Another solution is to use regex to match your search value surrounded by commas if necessary:
SELECT *
FROM t1
WHERE t1.nighborhood REGEXP CONCAT('(^|, )', myValue, '(, |$)');
In general, it's bad design to store distinct values in a single column. The data should be normalized into a related table with a foreign key.
I'm querying a table that has a column with member_ids stuffed in a pipe delimited string. I need to return all rows where there is an 'exact' match for a specific member_id. How do I deal with other IDs in the string which might match 'part' of my ID?
I might have some rows as follows:
1|34|11|23
1011
23|1
5|1|36
64|23
If I want to return all rows with the member_id '1' (row 1, 3 and 4) is that possible without having to extract all rows and explode the column to check if any of the items in the resulting array match.
MySQL's regular expressions support a metacharacter class that matches word boundaries:
SELECT ...
FROM mytable
WHERE member_ids REGEXP '[[:<:]]1[[:>:]]'
See http://dev.mysql.com/doc/refman/5.6/en/regexp.html
If you don't like that, you can search using a simpler regular expression, but you have to escape the pipes because they have special meaning to regular expressions. And you also have to escape the escaping backslashes so you get literal backslashes through to the regular expression parser.
SELECT ...
FROM mytable
WHERE member_ids REGEXP '\\|1\\|'
You can do this in one expression if you modify your strings to include a delimiter at the start and the end of the string. Then you don't have to add special cases for beginning of string and end of string.
Note this is bound to do a table-scan. There's no way to index a regular expression match in MySQL. I agree with #MichaelBerkowski, you would be better off storing the member id's in a subordinate table, one id per row. Then you could search and sort and all sorts of other things that the pipe-delimited string makes awkward, inefficient, or impossible. See also my answer to Is storing a delimited list in a database column really that bad?
'|' has a specific meaning in REGEXP. So suppose that the ids are separated by another delimiter like '~'.
Then you can run this code:
SELECT * FROM `t1`
where (Address Regexp '^1~') or
(Address Regexp '~1$') or
(Address Regexp '^1$') or
(Address Regexp '~1~')
I have 2 fields in my table: start_date and title.
start_date is NULL.
title contains string like this: 'treatment at date 11/12/2012, at ... '.
I want to copy only the date intostart_date(fromtitle` field.)
what query will do that?
Thank you very match!
You can't. Mysql's support for regexp is only used in the where-part.
You have to either extract it into something else (java, perl, ruby) and manipulate it there or you can try to use locate, substring and other string functions (but none of them are regexp)
MySQL support for regular expressions is very limited, but if the format of your title column is almost fixed, and the date is always followed by ', at ...' you could use STR_TO_DATE in conjunction with two SUBSTRING_INDEX:
UPDATE yourtable
SET start_date = STR_TO_DATE(
SUBSTRING_INDEX(SUBSTRING_INDEX(title, ', at', 1), ' ', -1), '%d/%m/%Y')
The first SUBSTRING_INDEX will return everything before the first ', at' substring, and the second one will return everything after the last space fount.
Please see fiddle here.
I considered dates in the format of day/month/year, if it is month/day/year just use '%m/%d/%Y'
It is not my code, its something that I need to get it done without modifying the structure of table. I know it would be very easy to just store date as MySQL date format but I cant do that.
There is a column in table which stores serialized array as a string. Now I need to select all rows whose 'date' is less than today.
This date is inside serialized array string.
Is there a way to compare it on mysql query? An example string is:
a:3:{s:4:"test";b:1;s:2:"se";i:1;s:4:"date";s:10:"2013-05-23";}
I need to compare the "date" from this string to mysql date using the following query:
"date" BETWEEN 2013-01-01 AND 2013-05-23
You can extract the date value (assuming it's always set off by "date";s:10) using nested SUBSTRING_INDEX calls. The inner one returns everything after "date";s:10" and the outer one cuts off the closing quote and whatever follows:
SUBSTRING_INDEX(SUBSTRING_INDEX(val, '"date";s:10:"', -1), '"', 1)
If val is a:3:{s:4:"test";b:1;s:2:"se";i:1;s:4:"date";s:10:"2013-05-23";} as in your example, this will return 2013-05-23. Then your query can be:
...
WHERE SUBSTRING_INDEX(SUBSTRING_INDEX(val, '"date";s:10:"', -1), '"', 1) BETWEEN 2013-01-01 AND 2013-05-23
Not pretty, but we can't expect pretty here :)
I think you should get date with substring with starting character -13 (13 from right side) and length of 10.
Something like this:
SUBSTR(field_name, -13, 10)
select * from postmeta where meta_key = 'your_meta_key' and meta_value REGEXP ('6')
SELECT telephone_number
FROM table
WHERE telephone_number REGEXP '^1[() -]*999[() -]*999[() -]*9999$';
how do i make so its valid for any number format and any number
like
407-888-0909
1(408)998-7654
7776654433
876-7788
right now its only valid for 1-999-999-9999
Use:
SELECT telephone_number
FROM table
WHERE telephone_number REGEXP '^1[() -]*[[:digit:]]{3}[() -]*[[:digit:]]{3}[() -]*[[:digit:]]{4}$';
Reference:
Pattern Matching
It isn't very wise to store phone numbers in a database with spaces, dashes, parentheses, etc. The most efficient way is to truncate all that garbage to a simple 10 digit number. That way you can actually store the number in an INTEGER based column instead of a VARCHAR.
SELECT telephone_number
FROM table
WHERE telephone_number REGEXP '[1]?[(]?[[:DIGIT:]]{3}[)]?[-]?[[:DIGIT:]]{3}[-]?[[:DIGIT:]]{4}'