I have the following query:
SELECT `admin_users`.*
FROM `admin_users`
WHERE (avatar REGEXP 'avatars/Name-[0-9]+.jpg+')
ORDER BY `admin_users`.`avatar`
DESC LIMIT 1
It's ok if I have something like:
avatars/Name-5.jpg
avatars/Name-6.jpg
But if I have, avatars/Name-15.jpg, for example, it doesn't return in query.
In other words, It only works for 1 digit, not for more. How can I solve it?
When comparing strings (an that is what avatar is), "avatars/Name-1..." comes before "avatars/Name-5..." simply because the string "1" comes before "5".
It is not practical to order those by an embedded number. This would do what you want, but it is pretty cryptic:
ORDER BY 0 + MID(avatar, 14)
To explain
MID will start at the 14th character of 'avatars/Name-15.jpg' and extract '15.jpg'.
0+ will take that string, convert it to a number and deliver the number 15. (When a string is turned into a number, the first characters are taken as long as it looks like a number. So, 0+'abc' will deliver 0, since there is nothing at the beginning of abc that looks like a number.)
If the left part were not exactly 14 characters in all cases, the trick will fail. And it may get so complicated as to be 'impossible' in SQL.
Related
I have a column with a series of letters and numbers between aa01 and ZZ99. I can't seem to figure out how to search the column for a certain range of those such as aa00 to BZ99.
I tried using a between function such as the one below but it didnt work:
SELECT test_name
FROM Test
WHERE test_series BETWEEN 'aa00' and 'BZ99'
GROUP BY test_name
Edit:I tried adding quotes and it still does not return anything.(I added it above as well)
Edit2: MySQL is the engine.
BETWEEN requires the lower value to be first. Since upper case characters come before lower case, switch the order; but be certain that's the between values you're after!.
SELECT test_name
FROM Test
WHERE test_series BETWEEN 'BZ99' and 'aa00'
GROUP BY test_name
Since I can't comment, I'll add this here as an answer instead. This explains it pretty well.
SQL BETWEEN for text vs numeric values
Edit: specifically, this part, watch your ASCII values:
Similarly, the expression:
where food_name BETWEEN 'G' AND 'O'
will match 'O', but not any other string beginning with 'O'.
Once simple kludge is to use "~". This has the largest 7-bit ASCII value, so for English-language applications, it usually works well:
where food_name between 'G' and 'O~'
I have the following MySQL:
SELECT scott, title FROM stampitemdetails WHERE scott REGEXP '^RW[0-9]+$' ORDER BY CAST(scott AS UNSIGNED), scott;
The problem is that this query is bringing back my results ordered like this:
RW1
RW10
RW11
RW2
When they should be like this:
RW1
RW2
RW10
RW11
How do I do natural sorting when my value starts with a character and ends with a number?
What if the length of the RW can fluctuate.... meaning it could be S, or REN, or some other characters of unknown length before the number? Keep that in mind.
By the way, I have the RegEx in the query because in my PHP code the RW can be replaced with other characters.
You should extract the numerical part
SELECT scott, title
FROM stampitemdetails
WHERE scott REGEXP '^RW[0-9]+$'
ORDER BY substr(scott, 1,2), CAST(substr(scott, 3, 100) AS UNSIGNED);
I have a real hack to offer you.
ORDER BY 0+REVERSE(CAST(0+REVERSE(scott) AS CHAR))
What does this do?
starting with your data for example RW123 ...
it reverses the order of the characters in this column of yours. 321WR
by adding 0 to that, it converts it to a number, which scrubs off the now-trailing letters. 321
it casts that number back to a character string. 321
it reverses that character string again 123
by adding 0 to that character string it casts it again as a number. 123
it orders by that number (as a number, not a character string).
Told you it's a hack.
If you have a bunch of different letter prefixes and you want to order with those lexically and then with the numbers, you need this pattern.
ORDER BY letters, numbers
To get the first part of that, you'll have to extract just the letters.
You can do that with
REPLACE(scott,REVERSE(CAST(0+REVERSE(scott) AS CHAR)),'')
This replaces the numbers in your character string with nothing. So now you need
ORDER BY REPLACE(scott,REVERSE(CAST(0+REVERSE(scott) AS CHAR)),''),
0+REVERSE(CAST(0+REVERSE(scott) AS CHAR))
Please please write a comment explaining this to your successor if you use it in code.
SELECT update_log, update_idccode, update_filenumber, update_filetype, update_timedate
FROM updates_log
WHERE substring(update_idccode,0,7) ='idc2997%' AND update_filetype = 'E'
ORDER BY update_log DESC
I am trying to get this to get the first 7 characters of my update_idccode table column. I cannot get it to work. Any thoughts?
You're pulling out 7 chars from your column, and comparing them against an 8-char string. In other words, it is imposssible for a 7-char word to ever be identical to an 8-char word.
Try
WHERE substring(update_idccode,0,7) = 'idc2997' ...
instead. As an alternative,
WHERE update_idccode LIKE 'idc2997%' ...
would also work. The % suggests you may have been trying this, but % is only relevant as a wildcard in LIKE comparisons, not = equality testing.
I have a column varchar[25] with this data inside :
886,-886
-886
0,-1234
1234
(empty)
0
the numbers might change in size from a 1 digit to a n digits.
and I need to be able to pull any row that has at least one positive number in it
I was thinking that something like
REGEXP '[^-,][0-9]+'
but this pulls -886 as 88 matches the regexp
you probably does not require regex
COL not like '-%' AND COL not like '%,-%'
however, this is the bad example of storing into incorrect data type,
split , and store into multiple rows ...and you can save some time for handling something like this question
Try using this :
"[^-\d]\d+\b"
which should work if i understood your question correctly.
a good regex reference table : http://www.regular-expressions.info/reference.html
I was able to figure out the best solution:
`COL` NOT LIKE '%-%'
I forgot to mention that the column might also contain words like:
all,-886
none,886
0,1,2,3,none
0
etc...
Try
REGEXP '[[:<:]][^-,][0-9]+[[:>:]]'
The :<: and :>: portions indicate word boundaries.
^\b\d+\b$
will give you positive integers.
^[^-]\d+((,([^-]\d+))?)+$
will give you only the lists where all the values are positive integers
For a list with any positive integer (but all valid integers negative or positive) I thinks this will check out:
^((-\d+,)?)+[^-]\d+((,([^-]\d+))?|(,-\d+)?)+$
Here's a great site for Regular Expressions:
http://gskinner.com/RegExr/
I use it all the time for testing live.
I need to make a selection based on the first 2 characters of a field, so for example
SELECT * from table WHERE postcode LIKE 'rh%'
But this would select any record that contains those 2 characters at any point in the "postcode" field right? I am in need of a query that just selects the first 2 characters. Any pointerS?
Thanks
Your query is correct. It searches for postcodes starting with "rh".
In contrast, if you wanted to search for postcodes containing the string "rh" anywhere in the field, you would write:
SELECT * from table WHERE postcode LIKE '%rh%'
Edit:
To answer your comment, you can use either or both % and _ for relatively simple searches. As you have noticed already, % matches any number of characters whereas _ matches a single character.
So, in order to match postcodes starting with "RHx " (where x is any character) your query would be:
SELECT * from table WHERE postcode LIKE 'RH_ %'
(mind the space after _). For more complex search patterns, you need to read about regular expressions.
Further reading:
http://dev.mysql.com/doc/refman/5.1/en/pattern-matching.html
http://dev.mysql.com/doc/refman/5.1/en/regexp.html
LIKE '%rh%' will return all rows with 'rh' anywhere
LIKE 'rh%' will return all rows with 'rh' at the beginning
LIKE '%rh' will return all rows with 'rh' at the end.
If you want to get only first two characters 'rh', use MySQL SUBSTR() function
http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_substr
Dave, your way seems correct to me (and works on my test data). Using a leading % as well will match anywhere in the string which obviously isn't desirable when dealing with postcodes.