Pattern for LIKE in SQL Statement - mysql

I would like to select all rows that start with any character.
SELECT * FROM table WHERE field LIKE '[a-z]%' ;
The type of rows I would like to find look like this:
ID DATA
993 DEF055900960
994 DEF055900961
995 DEF055900964
996 DEF056102254
997 DEF056131201
I have unsucessfully tried RLIKE and REGEXP and also added upper case A-Z ot the pattern.
Why is the following not working?

SELECT * FROM table WHERE field RLIKE '[a-z]' ;
SQL Fiddle Demo
I went through here to read about Pattern Matching in Mysql

Try this instead:
SELECT * FROM table WHERE field LIKE '[^A-Z]%';

Try this.
SELECT `firstname`
FROM `users`
WHERE firstname
REGEXP BINARY '^[A-Z]'

Use REGEXP
http://dev.mysql.com/doc/refman/5.1/en/regexp.html#operator_regexp
For example, assume we have this data set.
mysql> select * from a;
+------+
| b |
+------+
| abc |
| zxxb |
| kkfy |
| 0002 |
+------+
4 rows in set
We want to select everything with the a-z pattern
mysql> SELECT * FROM a WHERE b REGEXP BINARY '[a-z]';
+------+
| b |
+------+
| abc |
| zxxb |
| kkfy |
+------+
3 rows in set
SQLFiddle
For your data set
SQLFiddle
Use the regular expression [a-zA-Z0-9]
mysql> SELECT * FROM a WHERE b REGEXP BINARY '[a-zA-Z0-9]';
+--------------+
| b |
+--------------+
| DEF055900960 |
| DEF055900961 |
| DEF055900964 |
| DEF056102254 |
| DEF056131201 |
+--------------+
5 rows in set

Related

MySQL - Get all string sizes stored in a field

I would like to get all string sizes that are stored in a field myfield which is a varchar(128), along with their occurrences (i.e. the number of rows with that specific length). This is what I have so far:
MySQL > SELECT SUM(CHAR_LENGTH(myfield)=5) as occurr from mytable;
+--------+
| occurr |
+--------+
| 9194 |
+--------+
1 row in set (0.39 sec)
MySQL > SELECT SUM(CHAR_LENGTH(myfield)=6) as occurr from mytable;
+--------+
| occurr |
+--------+
| 11636 |
+--------+
1 row in set (0.44 sec)
MySQL > SELECT SUM(CHAR_LENGTH(myfield)=7) as occurr from mytable;
+--------+
| occurr |
+--------+
| 19022 |
+--------+
1 row in set (0.48 sec)
Is there a way to get this data with a single SQL command? Something like this output:
+--------+--------+
| length | occurr |
+--------+--------+
| 5 | 9194 |
+--------+--------+
| 6 | 11636 |
+--------+--------+
| 7 | 19022 |
+--------+--------+
You can simply use:
SELECT CHAR_LENGTH(myfield) AS length, COUNT(*) AS occurr
FROM mytable
WHERE CHAR_LENGTH(myfield) IN (5,6,7)
GROUP BY CHAR_LENGTH(myfield)
You can, of course, remove the WHERE clause, if you are not interested in some specific character lengths.
SELECT CHAR_LENGTH(my_field) ASlength, COUNT(*) ASoccurrFROMmytableGROUP BY CHAR_LENGTH(my_field)
I was still typing as the other answer came up. Basically the same - except no limit on what CHAR_LENGTH() is included.
SELECT CHAR_LENGTH(myfield) as length, COUNT(*) as occurence FROM mytable WHERE CHAR_LENGTH(myfield) BETWEEN 4 and 6 GROUP BY length
edit: I posted this more or less simultaniously to the identical answers above. I did of course not intend to steal an answer.

Using MySQL "NOT IN" but allowing for substrings

I am trying to query for rows that are not in another set of rows. However, the other set of rows may contain strings that include strings from the first table.
I'm confusing myself trying to explain so I'll use the following example tables:
mysql> DESCRIBE tablea;
+------------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+-------+
| name | char(40) | NO | PRI | | |
+------------+----------+------+-----+---------+-------+
mysql> DESCRIBE tableb;
+------------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+-------+
| nametag | char(40) | NO | PRI | | |
+------------+----------+------+-----+---------+-------+
mysql> SELECT name FROM tablea;
+------------+
| name |
+------------+
| cat |
| dog |
| cow |
+------------+
mysql> SELECT nametag FROM tableb;
+------------+
| nametag |
+------------+
| wolf |
| dog |
| browncow |
+------------+
I am trying to find a method similar to the NOT IN operation, however because cow is "in" browncow, I also want to exclude this value.
mysql> SELECT name FROM tablea WHERE name NOT IN ( SELECT nametag FROM tableb );
+------------+
| name |
+------------+
| cat |
| cow |
+------------+
# I am looking for something that would only return "cat" for this example.
Is there any operation where I can search for rows that aren't contained in another set with additional modifiers?
You could use an anti-join pattern, with a LIKE predicate to do the matching. (The anti-join is an outer join, to return all the rows from one table, along with matches from another table, and then a predicate to exclude the rows that had a match
SELECT a.name
FROM tablea a
JOIN tableb b
ON b.nametag LIKE CONCAT('%',a.name,'%')
WHERE b.nametag IS NULL
(Any rows from a that had a matching row from b... the row from b will have a non-NULL value. Or, to put it another way... rows from a that didn't have a matching row in b will have a NULL value for the columns from b.)
If there's a row in a that has name='cow', and a row from b that has nametag='browncow', those rows will match.
The row from a with name='cat' will only be returned if the string 'cat' doesn't appear in any values of b.nametag.
NOTE: The percent and underscore characters are wildcards in the LIKE predicate. If you want to do matching on those characters, you'd need to "escape" those with a backslash. There's similar issues using a REGEXP match, but a lot more possible mischievous characters.
There are other query patterns that will return an equivalent result.
For example:
SELECT a.name
FROM tablea a
WHERE NOT EXISTS
( SELECT 1
FROM tableb b
WHERE b.nametag LIKE CONCAT('%',a.name,'%')
)
Personally, I prefer the anti-join pattern.
Use "NOT EXISTS" along with INSTR
select *
from tablea a
where not exists(select 1 from tableb b where INSTR(a.name, b.nametag) > 0)
;
To exclude empty strings:
select *
from tablea a
where not exists(select 1 from tableb b where INSTR(a.name, b.nametag) > 0)
and length(a.name) > 0
;

MySQL : check if a "value" is in one field but is not in another one?

I have a table like this:
id | value1 | value2
-------------------------
1 | a,b,c,d | a,d,e,f
-------------------------
2 | d,e,f,a |
-------------------------
3 | a,x,y,z | d,e,f
How can I get all rows that have "a" in [value1] but don't have "a" in [value2]?
It should be this:
2 | d,e,f,a |
-------------------------
3 | a,x,y,z | d,e,f
Thanks in advance!
You should think about normalization and never store data as comma separated string. However in this case you may use find_in_set, which is not efficient in long run. So while you are normalizing data (assuming you will do it), in the meanwhile you may use the following.
mysql> select find_in_set('a','a,b,c,d') as pos ;
+-----+
| pos |
+-----+
| 1 |
+-----+
1 row in set (0.02 sec)
mysql> select find_in_set('a','d,e,f') as pos ;
+-----+
| pos |
+-----+
| 0 |
+-----+
1 row in set (0.00 sec)
So the query becomes
select * from table_name
where
find_in_set('a',value1) > 0
and find_in_set('a',value2) = 0
Try this query:
SELECT *
FROM `table`
WHERE `value1` LIKE '%a%'
AND `value2` NOT LIKE '%a%'
if table name is 'test'
select * from test where value1 like '%a%' and value2 not like '%a%';

Find and replace a specific part of a string with a backslash in a field

For example this is myTable:
| i | data |
+---+---------+
| 1 | d\one |
| 2 | d\two |
| 3 | d\three |
But I want to change it to:
| i | data |
+---+-------+
| 1 | one |
| 2 | two |
| 3 | three |
I know how to find a specific part of a string with a backslash in a field:
SELECT * FROM myTable WHERE data LIKE 'd%\%'
I know how to find & replace a field a value, only this query won't work:
UPDATE myTable SET data=REPLACE(data,'d\','') WHERE data LIKE 'd%\%'
You need to escape the backslash
UPDATE myTable
SET data = REPLACE(data,'d\\','')
WHERE data INSTR('d\\') = 1
SQLFiddle demo
I hope you should put triple slash \\\ instead of double slash \\ in Like Clause. As I have tried I am unable to pick data from using \\
SELECT * FROM mytable WHERE data LIKE 'd\\%';
Empty set (0.00 sec)
mysql> SELECT * FROM mytable WHERE data LIKE 'd\\\%';
+---------+
| data |
+---------+
| d\one |
| d\two |
| d\three |
+---------+
3 rows in set (0.00 sec)
mysql> SELECT REPLACE(data,'d\\','') FROM mytable WHERE data LIKE 'd\\\%';
+------------------------+
| REPLACE(data,'d\\','') |
+------------------------+
| one |
| two |
| three |
+------------------------+
3 rows in set (0.00 sec)
mysql> UPDATE mytable SET data = REPLACE(data,'d\\','') WHERE data LIKE 'd\\\%';
Query OK, 3 rows affected (0.06 sec)
Rows matched: 3 Changed: 3 Warnings: 0
mysql> SELECT * FROM mytable;
+-------+
| data |
+-------+
| one |
| two |
| three |
+-------+
3 rows in set (0.00 sec)
try this one..
UPDATE myTable SET `data`=REPLACE(`data`,'d\','');

How to filter the item in mysql database into given letter ranges

I have a query to filter the result in mysql database into given letter ranges: I want to display the items who starts with letter a-f. I uses this query but I think there is a better query to do that.
SELECT DISTINCT title FROM tables WHERE LEFT(title, 1) ='a' AND LEFT(title, 1)='b' ..... AND LEFT(title, 1)='f';
MySQL (and probably all databii) evaluate words that begin with 'B' as being greater than 'a' and less than 'c'.
So you can simply check for values between 'a' and 'f'.
SELECT DISTINCT title FROM tables WHERE title >= 'a' AND title < 'g';
This should be more efficient than a regex (much as I love Regular Expressions), and is easier to read.
You can use regex something like
SELECT DISTINCT title FROM tables WHERE title REGEXP '^[a-f]'
It's case insensitive. But you might want to remove DISTINCT if you do not want single result for uppercase and lowercase word. For example,
mysql> select * from name;
+------+--------+
| id | title |
+------+--------+
| 1 | anisgt |
| 1 | bnisgt |
| 1 | dnisgt |
| 1 | gnisgt |
| 1 | hnisgt |
| 1 | Hnisgt |
| 1 | Pnisgt |
+------+--------+
7 rows in set (0.00 sec)
mysql> SELECT DISTINCT title FROM name WHERE title REGEXP '^[f-z]';
+--------+
| title |
+--------+
| gnisgt |
| hnisgt |
| Pnisgt |
+--------+
3 rows in set (0.00 sec)
mysql> SELECT title FROM name WHERE title REGEXP '^[f-z]';
+--------+
| title |
+--------+
| gnisgt |
| hnisgt |
| Hnisgt |
| Pnisgt |
+--------+
4 rows in set (0.00 sec)
Edit#1 updated case for upper-case, lower case query and example for without distinct
However you can force case sensitivity using binary key word like
mysql> SELECT DISTINCT binary title FROM name WHERE title REGEXP '^[f-z]';
+--------------+
| binary title |
+--------------+
| gnisgt |
| hnisgt |
| Hnisgt |
| Pnisgt |
+--------------+
4 rows in set (0.00 sec)
Edit:2 case sensitive search added