How do I get the type of a variable in MySQL? - mysql

I'm trying to change a table field that contains decimal numbers from varchar(255) to decimal(12,2). And before I do that, I'd like to find out if there is information that would get deleted in the process: are there any rows where this field contains something other than a decimal(12,2).
I'm stumped how to do this. Apparently there isn't a string function like is_numeric() in PHP. I already tried casting the field to decimal and then comparing it with the original string, but this returns TRUE even for obvious cases where it should not:
select ('abc' = convert('abc', decimal(12,2)));
returns 1
Any help? How do I find out if a string contains something other than a decimal in MySQL? Thanks.

Stupid me, I have to cast twice (to decimal and back to char), which makes it work:
select ('abc' = convert(convert('abc', decimal(12,2)), char(255)));
returns 0
Thanks.

If you want to examine if the strings are actually floating points numbers, you could also use a regular expression. The following regex can help :)
SELECT '31.23' REGEXP '^[[:digit:]]+([.period.][[:digit:]]+)?$'; # returns 1
SELECT '31' REGEXP '^[[:digit:]]+([.period.][[:digit:]]+)?$'; # returns 1
SELECT 'hey' REGEXP '^[[:digit:]]+([.period.][[:digit:]]+)?$'; # returns 0

Related

How to find variable pattern in MySql with Regex?

I am trying to pull a product code from a long set of string formatted like a URL address. The pattern is always 3 letters followed by 3 or 4 numbers (ex. ???### or ???####). I have tried using REGEXP and LIKE syntax, but my results are off for both/I am not sure which operators to use.
The first select statement is close to trimming the URL to show just the code, but oftentimes will show a random string of numbers it may find in the URL string.
The second select statement is more rudimentary, but I am unsure which operators to use.
Which would be the quickest solution?
SELECT columnName, SUBSTR(columnName, LOCATE(columnName REGEXP "[^=\-][a-zA-Z]{3}[\d]{3,4}", columnName), LENGTH(columnName) - LOCATE(columnName REGEXP "[^=\-][a-zA-Z]{3}[\d]{3,4}", REVERSE(columnName))) AS extractedData FROM tableName
SELECT columnName FROM tableName WHERE columnName LIKE '%___###%' OR columnName LIKE '%___####%'
-- Will take a substring of this result as well
Example Data:
randomwebsite.com/3982356923abcd1ab?random_code=12480712_ABC_DEF_ANOTHER_CODE-xyz123&hello_world=us&etc_etc
In this case, the desired string is "xyz123" and the location of said pattern is variable based on each entry.
EDIT
SELECT column, LOCATE(column REGEXP "([a-zA-Z]{3}[0-9]{3,4}$)", column), SUBSTR(column, LOCATE(column REGEXP "([a-zA-Z]{3}[0-9]{3,4}$)", column), LENGTH(column) - LOCATE(column REGEXP "^.*[a-zA-Z]{3}[0-9]{3,4}", REVERSE(column))) AS extractData From mainTable
This expression is still not grabbing the right data, but I feel like it may get me closer.
I suggest using
REGEXP_SUBSTR(column, '(?<=[&?]random_code=[^&#]{0,256}-)[a-zA-Z]{3}[0-9]{3,4}(?![^&#])')
Details:
(?<=[&?]random_code=[^&#]{0,256}-) - immediately on the left, there must be & or &, random_code=, and then zero to 256 chars other than & and # followed with a - char
[a-zA-Z]{3} - three ASCII letters
[0-9]{3,4} - three to four ASCII digits
(?![^&#]) - that are followed either with &, # or end of string.
See the online demo:
WITH cte AS ( SELECT 'randomwebsite.com/3982356923abcd1ab?random_code=12480712_ABC_DEF_ANOTHER_CODE-xyz123&hello_world=us&etc_etc' val
UNION ALL
SELECT 'randomwebsite.com/3982356923abcd1ab?random_code=12480712_ABC_DEF_ANOTHER_CODE-xyz4567&hello_world=us&etc_etc'
UNION ALL
SELECT 'randomwebsite.com/3982356923abcd1ab?random_code=12480712_ABC_DEF_ANOTHER_CODE-xyz89&hello_world=us&etc_etc'
UNION ALL
SELECT 'randomwebsite.com/3982356923abcd1ab?random_code=12480712_ABC_DEF_ANOTHER_CODE-xyz00000&hello_world=us&etc_etc'
UNION ALL
SELECT 'randomwebsite.com/3982356923abcd1ab?random_code=12480712_ABC_DEF_ANOTHER_CODE-aaaaa11111&hello_world=us&etc_etc')
SELECT REGEXP_SUBSTR(val,'(?<=[&?]random_code=[^&#]{0,256}-)[a-zA-Z]{3}[0-9]{3,4}(?![^&#])') output
FROM cte
Output:
I'd make use of capture groups:
(?<=[=\-\\])([a-zA-Z]{3}[\d]{3,4})(?=[&])
I assume with [^=\-] you wanted to capture string with "-","\" or "=" in front but not include those chars in the result. To do that use "positive lookbehind" (?<=.
I also added a lookahead (?= for "&".
If you'd like to fidget more with regex I recommend RegExr

SQL SELECT everything after a certain character

I need to extract everything after the last '=' (http://www.domain.com?query=blablabla - > blablabla) but this query returns the entire strings. Where did I go wrong in here:
SELECT RIGHT(supplier_reference, CHAR_LENGTH(supplier_reference) - SUBSTRING('=', supplier_reference))
FROM ps_product
select SUBSTRING_INDEX(supplier_reference,'=',-1) from ps_product;
Please use this for further reference.
Try this (it should work if there are multiple '=' characters in the string):
SELECT RIGHT(supplier_reference, (CHARINDEX('=',REVERSE(supplier_reference),0))-1) FROM ps_product
Try this in MySQL.
right(field,((CHAR_LENGTH(field))-(InStr(field,','))))
In MySQL, this works if there are multiple '=' characters in the string
SUBSTRING(supplier_reference FROM (LOCATE('=',supplier_reference)+1))
It returns the substring after(+1) having found the the first =
If your string is
str = 'abc=def=ghi'
To select to the right:
select substring_index(str,'=',-1) from tablename ==> result is 'ghi'
select substring_index(str,'=',-2) from tablename ==> result is 'def=ghi'
To select to the left
select substring_index(str,'=',-1) from tablename ==> result is 'abc'
select substring_index(str,'=',2) from tablename ==> result is 'abc=def'
I've been working on something similar and after a few tries and fails came up with this:
Example:
STRING-TO-TEST-ON = 'ab,cd,ef,gh'
I wanted to extract everything after the last occurrence of "," (comma) from the string... resulting in "gh".
My query is:
SELECT SUBSTR('ab,cd,ef,gh' FROM (LENGTH('ab,cd,ef,gh') - (LOCATE(",",REVERSE('ab,cd,ef,gh'))-1)+1)) AS `wantedString`
Now let me try and explain what I did ...
I had to find the position of the last "," from the string and to calculate the wantedString length, using LOCATE(",",REVERSE('ab,cd,ef,gh'))-1 by reversing the initial string I actually had to find the first occurrence of the "," in the string ... which wasn't hard to do ... and then -1 to actually find the string length without the ",".
calculate the position of my wantedString by subtracting the string length I've calculated at 1st step from the initial string length:
LENGTH('ab,cd,ef,gh') - (LOCATE(",",REVERSE('ab,cd,ef,gh'))-1)+1
I have (+1) because I actually need the string position after the last "," .. and not containing the ",". Hope it makes sense.
all it remain to do is running a SUBSTR on my initial string FROM the calculated position.
I haven't tested the query on large strings so I do not know how slow it is. So if someone actually tests it on a large string I would very happy to know the results.
For SQL Management studio I used a variation of BWS' answer. This gets the data to the right of '=', or NULL if the symbol doesn't exist:
CASE WHEN (RIGHT(supplier_reference, CASE WHEN (CHARINDEX('=',supplier_reference,0)) = 0 THEN
0 ELSE CHARINDEX('=', supplier_reference) -1 END)) <> '' THEN (RIGHT(supplier_reference, CASE WHEN (CHARINDEX('=',supplier_reference,0)) = 0 THEN
0 ELSE CHARINDEX('=', supplier_reference) -1 END)) ELSE NULL END
SELECT NULLIF(SUBSTRING_INDEX(column, '=', -1), column)

mysql substr not working like php

Please help me resolve my query when using query - I just want to subtract a few characters and then use the % to find the matching LIKE:
select * from `providers` WHERE `name` LIKE SUBSTR('telin',1,4)%
Please let me know what i'm doing wrong, any kind of help is greatly appreciated!
Assuming telin is a column name rather than the literal string, it should be quoted in backticks. If it is the literal string, then there is obviously no need to extract a substring from it. I suspect however, that it was the result of a PHP variable you pasted here after echoing out the full query, then it is correctly single-quoted.
Anyway, you will need to concatenate the SUBSTR() result onto the '%' via CONCAT():
SELECT * FROM `providers` WHERE `name` LIKE CONCAT(SUBSTR(`telin`,1,4), '%');
But better would be to use LEFT() to compare the first 4 characters of each:
SELECT * FROM `providers` WHERE LEFT(`name`, 4) = LEFT(`telin`,4);

Why does this search query return nothing?

I have this table under user_name='high'
function_description :
akram is in a date
test
akram is studying
test4
kheith is male
test3
I want a query that returns results of field that have at least an 'akram'
SELECT *
FROM functions
WHERE 'isEnabled'=1
AND 'isPrivate'=1
AND user_name='high'
AND function_description LIKE '%akram%'
and this returns absolutely nothing!
Why?
You are listing the column names as if they are strings. This is why it returns nothing.
Try this:
SELECT *
FROM functions
WHERE user_name='high'
AND function_description LIKE '%akram%'
edit: After trying to re-read your question... are isEnabled and isPrivate columns in this table?
edit2: updated.. remove those unknown columns.
You are comparing strings 'isEnabled' with integer 1, which likely leads to the integer being converted to a string, and the comparison then fails. (The alternative is that the string is converted to an integer 0 and the comparison still fails.)
In MySQL, you use back-quotes, not single quotes, to quote column and table names:
SELECT *
FROM `functions`
WHERE `isEnabled` = 1
AND `isPrivate` = 1
AND `user_name` = 'high'
AND `function_description` LIKE '%akram%'
In standard SQL, you use double quotes to create a 'delimited identifier'; in Microsoft SQL Server, you use square brackets around the names.
Please show the schema more carefully (column names, sample values, types if need be) next time.

MySQL SELECT WHERE 'a' IN (`field`)

I know it is not an appropriate technique to have a structure of MySQL table as such, but I have to work with such. The problem is, that the field in table has value with comma seperated integers, like "1,3,5,7,10" and I want the query to return rows, in which field has a to the query passed number in it, like:
SELECT * FROM `table` WHERE '5' IN (`field_in_table`)
However, it does not work, if, in this case, '5' is not the first number in the field.
Any advises, how to solve that?
Thanks in advance,
Regards,
Jonas
Have a look at
FIND_IN_SET
Returns a value in the range of 1 to N
if the string str is in the string
list strlist consisting of N
substrings. A string list is a string
composed of substrings separated by
“,” characters. If the first argument
is a constant string and the second is
a column of type SET, the
FIND_IN_SET() function is optimized to
use bit arithmetic. Returns 0 if str
is not in strlist or if strlist is the
empty string.
You could use WHERE field_in_table LIKE '%5%' instead.
Of course, the problem would be, '1,59,98' would return as wel.
SELECT * FROM table WHERE field_in_table LIKE '%5'");
should work
You could try
SELECT *
FROM table
WHERE '%,5,%' LIKE field_in_table OR
'%,5' LIKE field_in_table OR
'5,%' LIKE field_in_table;
A better approach might be to use regular expressions, a subject on which I am not an authority.
SELECT *
FROM table
WHERE FIELD LIKE '%,5,%' OR
FIELD LIKE '5,%' OR
FIELD LIKE '%,5'