MySQL Tricky Regex - mysql

I have a field which has strings (commas part of string) like "X1,X2,X3,X4,X5".
Let's take example MySQL table-
id FIELD1
1 X1,X3
2 X1,X3,X4
3 X2,X3,X4
4 X2,X4
5 X1,X3,X4,X5,X6
let Q = "X1,X3,X4,X5"
Now, what is the query to get rows where all the characters of FIELD1 value are contained in Q. Q is such that there are only 8 characters(X1,X2..) of such kind, and characters in a string are not repeated.
Select id FIELD WHERE "...Some regex on characters of Q...."
In other words,
it should return, row 1, 2 as X1, X3, X4 present in Q.
It should not return row 3,4,5 as X2,X6 is not present in Q.
Thank you so much

As juergen d said before me, your DB structure is faulty.
If you are using this structure, the ugly SQL query you'll get is the following:
SELECT id FROM Crooked_Table WHERE (FIELD1 LIKE '%X1%' OR FIELD1 LIKE '%X3%' OR FIELD1 LIKE '%X4%' OR FIELD1 LIKE '%X5%') AND NOT (FIELD1 LIKE '%X2%' OR FIELD1 LIKE '%X6%')
And you'll need to cover all possible comma-separated values in the query, otherwise it won't work.

Related

how to fetch data from json array field in sql

I am using node.js with squel.js for SQL database.
I am storing array of string into one table field.
Let us say, My table name is like XYZ.
And my table data is like
id col2
1 '["a", "b", "x", "y"]'
2 '["x", "y", "q"]'
3 '["q", "e"]'
4 '["p", "q"]'
Now i want to know how to make query for search like
if i want to how to make query if i want to fetch records like
If i want to fetch all records which contains like ["x", "y"]. In this scenario i want expect result id 1 and 2.
If i want to fetch all records which contains like ["q"]. In this scenario i want expect result 2 and 4.
Please help me here i stuck here. Thanks in advance.
If I understand your question correctly,just use LIKE can do it
For the first requirement,you can use
SELECT * FROM yourtable WHERE col2 LIKE `%"x"%` AND col2 LIKE `%"y"%`
OR
SELECT * FROM yourtable WHERE col2 LIKE `%"x","y"%`
Since I do not know the format exactly,is it just check match x and y? Or just match "x","y" exactly?
For the second requirement,you can use
SELECT * FROM yourtable WHERE col2 LIKE `%"q"%`
col2 can be a JSON column, thus you can do something like:
SELECT * FROM XYZ WHERE JSON_CONTAINS(col2, JSON_ARRAY('x', 'y'));
SELECT * FROM XYZ WHERE JSON_CONTAINS(col2, JSON_ARRAY('q'));
The second query would returns rows 2, 3 and 4, but I guess your expectation might be incorrectly stated, since 'q' exists in the col2 array for all of those.

Selecting double vs single letter at end of string in MySQL

I am trying to write a MySQL select statement where I am trying to select values based on the last letter or letters of a string. The problem is... these values have double letters at the end of the string and I am not able to differentiate between them when getting results.
For example... I have the following 2 values in a table
1. Mens 3's AA
2. Mens 3's A
The query I am currently using returns both values when I only want to return #2 above. Here is the query:
SELECT divisions.div_id, divisions.div_lname
FROM divisions
WHERE LEFT(divisions.div_lname,1) = "M"
AND divisions.div_lname LIKE '%3%'
AND RIGHT(divisions.div_lname,1) = 'A'
ORDER BY divisions.div_nop, divisions.div_order
I really need to understand the best approach for selecting 1 but not the other when I have values that contain duplicate letters at the end of the string. Is there a regex approach that would work?
try using SUBSTRING_INDEX() like this, it'll return the last chunk after the space..so it won't return rows that have 'AA'..and only return row with 'A'
SELECT divisions.div_id, divisions.div_lname
FROM divisions
WHERE LEFT(divisions.div_lname,1) = "M"
AND divisions.div_lname LIKE '%3%'
AND SUBSTRING_INDEX(divisions.div_lname,' ',-1) = 'A'
ORDER BY divisions.div_nop, divisions.div_order

Length of a text list in MySQL (basic string manipulation)

I have a field of comma-separated lists in MySQL:
id field1
1 aa,bb,cc
2 aa
I would like to count the total number of elements, with overlap. In this case that would be 4: aa appears twice and so should be double-counted.
It would suffice to count the number of commas in each field and add 1, since my lists do not have quotes or escaping.
Let's try that:
select count(field1) + sum(CHAR_LENGTH(field1) - CHAR_LENGTH(REPLACE(field1,',','')))
from Table1;
Why do you use comma separated string?
Databases aren't made for that.
You have 2 possibilities :
- make a loop in a stored procedure,
- count it into the code which call this MySQL query...

find elements of a varchar in another varchar

i have a varchar field with the content like these:
a,b,c,d
e,d,a,c
b,q,d,e
i need to do a query that select only the rows with the field that has elements equals with an input string.
ex
input: c,a
rows selected:
a,b,c,d
e,d,a,c
is possible without use the OR (field like '%a%' OR field like '%c%') ?
thanks
Yes, you can use...
WHERE
myField LIKE '%a%' AND myField LIKE '%c%'
However, this does sound like you've got a nasty field in your SQL.
Normally, you would use a link-table to specify this kind of information:
Table1
id
otherdata...
Table2
id
letter
LinkTable
Table1Id
Table2Id
So in LinkTable you would have many entries that link your records. So instead of storing 'a,b,c,d' in a field, you have four link records:
Table1Id Table2Id
1 1 (a)
1 2 (b)
1 3 (c)
1 4 (d)
Yes but you need a trick: Create a second column which contains the same value but sorted:
a,b,c,d
a,c,d,e
b,d,e,q
Now, you can query for %a%c%
This won't work if the query string can be a substring of any unwanted value. If this is the case, you need quotes:
"a","b","c","d"
"a","c","d","e"
"b","d","e","q"
and query for %"a"%"c"%

Difference between LIKE and = in MYSQL?

What's the difference between
SELECT foo FROM bar WHERE foobar='$foo'
AND
SELECT foo FROM bar WHERE foobar LIKE'$foo'
= in SQL does exact matching.
LIKE does wildcard matching, using '%' as the multi-character match symbol and '_' as the single-character match symbol. '\' is the default escape character.
foobar = '$foo' and foobar LIKE '$foo' will behave the same, because neither string contains a wildcard.
foobar LIKE '%foo' will match anything ending in 'foo'.
LIKE also has an ESCAPE clause so you can set an escape character. This will let you match literal '%' or '_' within the string. You can also do NOT LIKE.
The MySQL site has documentation on the LIKE operator. The syntax is
expression [NOT] LIKE pattern [ESCAPE 'escape']
LIKE can do wildcard matching:
SELECT foo FROM bar WHERE foobar LIKE "Foo%"
If you don't need pattern matching, then use = instead of LIKE. It's faster and more secure. (You are using parameterized queries, right?)
Please bear in mind as well that MySQL will do castings dependent upon the situation: LIKE will perform string cast, whereas = will perform int cast. Considering the situation of:
(int) (vchar2)
id field1 field2
1 1 1
2 1 1,2
SELECT *
FROM test AS a
LEFT JOIN test AS b ON a.field1 LIKE b.field2
will produce
id field1 field2 id field1 field2
1 1 1 1 1 1
2 1 1,2 1 1 1
whereas
SELECT *
FROM test AS a
LEFT JOIN test AS b ON a.field1 = b.field2
will produce
id field1 field2 id field1 field2
1 1 1 1 1 1
1 1 1 2 1 1,2
2 1 1,2 1 1 1
2 1 1,2 2 1 1,2
According to the MYSQL Reference page, trailing spaces are significant in LIKE but not =, and you can use wildcards, % for any characters, and _ for exactly one character.
I think in term of speed = is faster than LIKE. As stated, = does an exact match and LIKE can use a wildcard if needed.
I always use = sign whenever I know the values of something. For example
select * from state where state='PA'
Then for likes I use things like:
select * from person where first_name like 'blah%' and last_name like 'blah%'
If you use Oracle Developers Tool, you can test it with Explain to determine the impact on the database.
The end result will be the same, but the query engine uses different logic to get to the answer. Generally, LIKE queries burn more cycles than "=" queries. But when no wildcard character is supplied, I'm not certain how the optimizer may treat that.
With the example in your question there is no difference.
But, like Jesse said you can do wildcard matching
SELECT foo FROM bar WHERE foobar LIKE "Foo%"
SELECT foo FROM bar WHERE foobar NOT LIKE "%Foo%"
More info:
http://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html
A little bit og google doesn't hurt...
A WHERE clause with equal sign (=) works fine if we want to do an exact match. But there may be a requirement where we want to filter out all the results where 'foobar' should contain "foo". This can be handled using SQL LIKE clause alongwith WHERE clause.
If SQL LIKE clause is used along with % characters then it will work like a wildcard.
SELECT foo FROM bar WHERE foobar LIKE'$foo%'
Without a % character LIKE clause is very similar to equal sign alongwith WHERE clause.
In your example, they are semantically equal and should return the same output.
However, LIKE will give you the ability of pattern matching with wildcards.
You should also note that = might give you a performance boost on some systems, so if you are for instance, searching for an exakt number, = would be the prefered method.
Looks very much like taken out from a PHP script. The intention was to pattern-match the contents of variable $foo against the foo database field, but I bet it was supposed to be written in double quotes, so the contents of $foo would be fed into the query.
As you put it, there is NO difference.
It could potentially be slower but I bet MySQL realises there are no wildcard characters in the search string, so it will not do LIKE patter-matching after all, so really, no difference.
In my case I find Like being faster than =
Like fetched a number of rows in 0.203 secs the first time then 0.140 secs
= returns fetched the same rows in 0.156 secs constantly
Take your choice
I found an important difference between LIKE and equal sign = !
Example: I have a table with a field "ID" (type: int(20) ) and a record that contains the value "123456789"
If I do:
SELECT ID FROM example WHERE ID = '123456789-100'
Record with ID = '123456789' is found (is an incorrect result)
If I do:
SELECT ID FROM example WHERE ID LIKE '123456789-100'
No record is found (this is correct)
So, at least for INTEGER-fields it seems an important difference...