We have a varchar(255) column and some values are integers, how do I isolate only the rows which contain integer values
This should work.
select *
from table
where column
regexp '^\-?[1-9][0-9]*$'
EDIT: thanks Alma Do for pointing out that my solution did not consider signed integers and leading zeroes! Also his solution is much more performant than using regular expressions.
You can do this with CAST():
SELECT * FROM t WHERE CAST(col AS SIGNED)=col
You can use REGEXP() for your issue, but I will not recommend that: for large tables CAST() will be extremely faster. Compare:
mysql> select benchmark(1E7, '17453454.6655744' REGEXP '^[0-9]+$');
+------------------------------------------------------+
| benchmark(1E7, '17453454.6655744' REGEXP '^[0-9]+$') |
+------------------------------------------------------+
| 0 |
+------------------------------------------------------+
1 row in set (17.59 sec)
With:
mysql> select benchmark(1E7, CAST('17453454.6655744' AS SIGNED)='17453454.6655744');
+-----------------------------------------------------------------------+
| benchmark(1E7, CAST('17453454.6655744' AS SIGNED)='17453454.6655744') |
+-----------------------------------------------------------------------+
| 0 |
+-----------------------------------------------------------------------+
1 row in set, 1 warning (0.36 sec)
-and see the difference.
Here col means, will have to provide column name which has to be checked that having intergers or not ..?
SELECT * FROM t WHERE CAST(col AS SIGNED)=col
Related
I have product tables in my database
Product table structure:
product_id | testid
------------------------------------
1 11,12,13
2 2,4
Below is my FIND_IN_SET query:
SELECT product_id FROM product
WHERE FIND_IN_SET(3, testid) > 0;
Output
0
Below is my LOCATE query:
SELECT product_id FROM product
WHERE LOCATE(3, testid) > 0;
output
1
My question
What is difference between FIND_IN_SET and LOCATE and what is the best way to find id in column
To put it in simple technical terms(PHP terminology), find_in_set is like substring function of PHP. It will accept a substring and a string as parameters, and return 1 if the substring is found within the string. It will return 0 if substring is not found.
On the contrary, LOCATE() returns the position of the first occurrence of a string within a string. It accepts, a substring and a string as parameters.
I think in your use case, find_in_set is the one you should go for. Because this is the one. find_in_set will return 1 if 3 is found in a row, where as locate will first occurance of 3 in the string even if it finds 31 or 300 as first element.
Difference between LOCATE() and FIND_IN_SET() Function
When using LOCATE() function for integers, suppose we need 1 to return from LOCATE() if integer 3 is in the set 1,2,3,4,5,.. the following MySQL commands can be written:
mysql> SELECT IF(LOCATE(3,'1,2,3,4,5,6,7,8,9')>0,1,0);
+-----------------------------------------+
| IF(LOCATE(3,'1,2,3,4,5,6,7,8,9')>0,1,0) |
+-----------------------------------------+
| 1 |
+-----------------------------------------+
1 row in set (0.06 sec)
The above command working rightly because the set contains the number 3 , but if we write the following commands, look what happened
mysql> SELECT IF(LOCATE(3,'11,12,13,14,15')>0,1,0);
+--------------------------------------+
| IF(LOCATE(3,'11,12,13,14,15')>0,1,0) |
+--------------------------------------+
| 1 |
+--------------------------------------+
1 row in set (0.02 sec)
Above the 3 is not present as a number three(3) in the given set, though the LOCATE() returns 1.
To avoid this type of situation you can use the FIND_IN_SET() function. Here is the example below:
mysql> SELECT IF(FIND_IN_SET(3,'11,12,13,4,5,6,7,8,9')>0,1,0);
+-------------------------------------------------+
| IF(FIND_IN_SET(3,'11,12,13,4,5,6,7,8,9')>0,1,0) |
+-------------------------------------------------+
| 0 |
+-------------------------------------------------+
1 row in set (0.05 sec)
So, LOCATE() function is very much suitable for string but not as much suitable for integer.
Examples, credits and some more information you can find here
So in your example FIND_IN_SET return 0 because there is no 3 in the given set, but LOCATE() returns 1 it treat the given set as a string but not a comma separated value, and the 3 present in the number 13
I was trying to feed a result of a query as a parameter for another query and all was working fine except this field that has a datatype of bit. so i tried to convert the value of the field using convert() and cast() but it seems to be not working as its returning this wierd symbol of a small rectange which hava three 0's and a 1. so can anyone tell me why this is happening and how to fix it , here is my query
select CONVERT(isMale , char(5)) from person;
and the thing is it gives me the correct answer when i dont use the convert but since am giving this result to another query as a parameter it causing me the problem.
you can use BIN function like this:
SELECT BIN(isMale +0) from person;
sample
MariaDB [yourschema]> SELECT BIN(b'1001' +0) ;
+-----------------+
| BIN(b'1001' +0) |
+-----------------+
| 1001 |
+-----------------+
1 row in set (0.00 sec)
MariaDB [yourschema]>
Here some stuff from MariaDB Manual:
Description
Converts numbers between different number bases. Returns a
string representation of the number N, converted from base from_base
to base to_base.
Returns NULL if any argument is NULL, or if the second or third
argument are not in the allowed range.
The argument N is interpreted as an integer, but may be specified as
an integer or a string. The minimum base is 2 and the maximum base is
36. If to_base is a negative number, N is regarded as a signed number. Otherwise, N is treated as unsigned. CONV() works with 64-bit
precision.
Some shortcuts for this function are also available: BIN(), OCT(),
HEX(), UNHEX(). Also, MariaDB allows binary literal values and
hexadecimal literal values.
BIN is a short form from CONV(value,from,to) where you can convert from base to base
so binary 1001 = 9 as int
here i give the value in decimal (14) and convert it from base 10 to base 2
MariaDB [yourschema]> SELECT CONV(14,10 ,2);
+-----------------+
| CONV(14,10 ,2) |
+-----------------+
| 1110 |
+-----------------+
1 row in set (0.00 sec)
so, if you want to have 0 on the left you can add a value like this
MariaDB [yourschema]> SELECT CONV(8192 + 14,10 ,2);
+------------------------+
| CONV(8192 + 14,10 ,2) |
+------------------------+
| 10000000001110 |
+------------------------+
1 row in set (0.00 sec)
and then you can get n chars from right:
MariaDB [yourschema]> SELECT RIGHT(CONV(8192 + 14,10 ,2),8);
+---------------------------------+
| RIGHT(CONV(8192 + 14,10 ,2),8) |
+---------------------------------+
| 00001110 |
+---------------------------------+
1 row in set (0.40 sec)
MariaDB [yourschema]>
I think you want to use CAST
select CAST(isMale as CHAR) from person;
seeing #Bernd Buffen answer i tried using the convert with +0 and it works , eventhough i dont know why
select CONVERT(isMale +0, char(5)) from person;
For example, I am having a column storing data like this.
Apple
12.5.126.40
Smite
Abby
127.0.0.1
56.5.4.8
9876543210
Notes
How to select out only the rows with data in IP format?
I have tried with '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$'
but I have no idea why it also matches 9876543210
You're going to need to use REGEXP to match the IP address dotted quad pattern.
SELECT *
FROM yourtable
WHERE
thecolumn REGEXP '^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$'
Technically, this will match values that are not valid IP addresses, like 999.999.999.999, but that may not be important. What is important, is fixing your data such that IP addresses are stored in their own column separate from whatever other data you have in here. It is almost always a bad idea to mix data types in one column.
mysql> SELECT '9876543210' REGEXP '^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$';
+---------------------------------------------------------------------------+
| '9876543210' REGEXP '^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$' |
+---------------------------------------------------------------------------+
| 0 |
+---------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT '987.654.321.0' REGEXP '^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$';
+------------------------------------------------------------------------------+
| '987.654.321.0' REGEXP '^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$' |
+------------------------------------------------------------------------------+
| 1 |
+------------------------------------------------------------------------------+
Another method is to attempt to convert the IP address to a long integer via MySQL's INET_ATON() function. An invalid address will return NULL.
This method is likely to be more efficient than the regular expression.
You may embed it in a WHERE condition like: WHERE INET_ATON(thecolumn) IS NOT NULL
SELECT INET_ATON('127.0.0.1');
+------------------------+
| INET_ATON('127.0.0.1') |
+------------------------+
| 2130706433 |
+------------------------+
SELECT INET_ATON('notes');
+--------------------+
| INET_ATON('notes') |
+--------------------+
| NULL |
+--------------------+
SELECT INET_ATON('56.99.9999.44');
+----------------------------+
| INET_ATON('56.99.9999.44') |
+----------------------------+
| NULL |
+----------------------------+
IS_IPV4() is a native mysql function that lets you check whether a value is a valid IP Version 4.
SELECT *
FROM ip_containing_table
WHERE IS_IPV4(ip_containing_column);
I don't have data, but I reckon that this must be the most solid and efficient way to do this.
There are also similar native functions that check for IP Version 6 etc.
This may not be the most efficient way, and it's not technically regex, but it should work:
SELECT col1 FROM t1 WHERE col1 LIKE '%.%.%.%';
you could also use the useful function inet_aton()
SELECT *
FROM yourtable
WHERE inet_aton(thecolumn) is not null
Lengthy but works fine:
mysql> SELECT '1.0.0.127' regexp '^([0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\\.([0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\\.([0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\\.([0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])$';
I have to get last 5 numbers using mysql.
My values are like YOT-A78514,LOP-C4521 ...
I have to get only last five char . How can I do this in query?
You can do this with RIGHT(str,len) function. Returns the rightmost len characters from the string str,
Like below:
SELECT RIGHT(columnname,5) as yourvalue FROM tablename
"Right"-function is the way to, using the substring may lead to an problem that is not so easy to notice:
mysql> select right('hello', 6);
+-------------------+
| right('hello', 6) |
+-------------------+
| hello |
+-------------------+
1 row in set (0.00 sec)
mysql> select substring('hello', -6);
+------------------------+
| substring('hello', -6) |
+------------------------+
| |
+------------------------+
1 row in set (0.00 sec)
But if you don't try to go past the start of the string, then substring of course works fine:
mysql> select substring('hello', -5);
+------------------------+
| substring('hello', -5) |
+------------------------+
| hello |
+------------------------+
1 row in set (0.00 sec)
Right is a good choice but you can also use substring like this-
SELECT Substring(columnname,-5) as value FROM table_name
SELECT row_id
FROM column_name
WHERE column_value LIKE '%12345';
This will return the "row_id" when "12345" is found to be the tailing suffix of the "column_value" within the "column_name".
And if you want to get a dinamic number of right characters after a character:
SELECT TRIM(
RIGHT(
database.table.field,
(LENGTH(database.table.field) - LOCATE('-',database.table.field))
)
)
FROM database.table;
SELECT SUBSTR('Stringname', -5) AS Extractstring;
My table filed's value is "<script type="text/javascript"src="http://localhost:8080/db/widget/10217EN/F"></script>",
I want to analyse this string and fetch the id 10217,how to do use mysql regex?
I know python regex group function can return the id 10217,but i'm not familiar with mysql regex.
Please help me,Thank you very much.
MySQL regular expressions do not support subpattern extraction. You will probably have better luck iterating over all of the rows in your database and storing the results in a new column.
As far as I know, you can't use MySQL's REGEXP for substring retrieval; it is designed for use in WHERE clauses and is limited to returning 0 or 1 to indicate failure or success at a match.
Since your pattern is pretty well defined, you can probably retrieve the id with a query that uses SUBSTR and LOCATE. It will be a bit of a mess since SUBSTR wants the start index and the length of the substring (it would be easier if it took the end index). Perhaps you could use TRIM to chop off the unwanted trailing part.
This query get the Id from the field
SELECT substring_index(SUBSTRING_INDEX(testvar,'/',-3),'EN',1) from testtab;
where as testtab - is table name , testvar - is field name
inner substring get string starts with last 3 / which is
mysql> SELECT SUBSTRING_INDEX(testvar,'/',-3) from testtab;
+----------------------------+
| SUBSTRING_INDEX(testvar,'/',-3) |
+----------------------------+
| 10217EN/F"> |
| 10222EN/F"> |
+----------------------------+
2 rows in set (0.00 sec)
outer substring get
mysql> SELECT substring_index(SUBSTRING_INDEX(testvar,'/',-3),'EN',1) from testtab;
+----------------------------------------------------+
| substring_index(SUBSTRING_INDEX(testvar,'/',-3),'EN',1) |
+----------------------------------------------------+
| 10217 |
| 10222 |
+----------------------------------------------------+
2 rows in set (0.00 sec)