mysql sort order, need slightly different result - mysql

I have a varchar column that I am currently sorting by using: ORDER BY (col_name+0)
This column contains both digits and non-digits, and the result of this sorting is this:
D3
D111
M123-M124
M136
4
9
10
25
37b
132
147-149
168b
168ca
This sorting is almost perfect for our application, but with one exception: we want the items that start with letters to display after those that start with numbers. This being the ideal result:
4
9
10
25
37b
132
147-149
168b
168ca
D3
D111
M123-M124
M136
I'm hoping this can be achieved in the select statement, rather than needing to loop through everything in code again after the select. Any ideas?

You can use this:
ORDER BY
col_name regexp "^[^0-9]",
case when col_name regexp "^[0-9]" then col_name + 0
else mid(col_name, 2, length(col_name )-1) + 0 end,
col_name
this will put rows that begins with a digit at the top. If col_name begins with a digit, I'm sorting by it's numeric value, if not I'm sorting by the numeric value of the string beginning at the second character.

Related

MYSQL - Find rows, where part of search string matches part of value in column

I wasn't able to find this anywhere, here's my problem:
I have a string like '1 2 3 4 5' and then I have a mysql table that has a column, let's call it numbers, that look like this:
numbers
1 2 6 8 9 14
3
1 5 3 6 9
7 8 9 23 44
10
I am trying to find the easiest way (hopefully in a single query) to find the rows, where any of the numbers in my search string (1 or 2 or 3 or 4 or 5) is contained in the numbers column. In the give example I am looking for rows with 1,2 and 3 (since they share numbers with my search string).
I am trying to do this with a single query and no loops.
Thanks!
The best solution would be to get rid of the column containing a list of values, and use a schema where each value is in its own row. Then you can use WHERE number IN (1, 2, 3, 4, 5) and join this with the table containing the rest of the data.
But if you can't change the schema, you can use a regular expression.
SELECT *
FROM yourTable
WHERE numbers REGEXP '[[:<:]](1|2|3|4|5)[[:<:]]'
[[:<:]] and [[:<:]] match the beginning and end of words.
Note that this type of search will be very slow if the table is large, because it's not feasible to index it.
Here is a start point (split string function) : http://blog.fedecarg.com/2009/02/22/mysql-split-string-function/ := SplitString(string,delimiter,position)
Create a function so it converts a string to an array := stringSplitted(string,delimiter)
Create a function so it compares two arrays :=arrayIntersect(array1, array2)
SELECT numbers
FROM table
WHERE arrayIntersect(#argument, numbers)
Two function definitions with loops and one single query without any loop
SELECT * FROM MyTable WHERE (numbers LIKE '%1%' OR numbers LIKE '%2%')
or you can also use REGEX something like this
SELECT * FROM events WHERE id REGEXP '5587$'

Transforming a column to have 10 Digits

I have a csv file that contains phone numbers, some of them have 9 digits and some of them have 10. Is there a command that would allow the transformation of the column such that numbers that have only 9 digits will have a 0 appended in front of the numbers.
For example,
if the column has values "443332332" and "0441223332", I would like to have the value of the one with 9 digits changed to "0443332332"?
Sorry, I should have elaborated.
I was wondering if there was a command to do it in SQLlite easily? I prefer not to use excel to transform the column as if I can get it to working with sqllite it would be so much easier and faster.
A more generic solution would be:
select substr('0000000000'||'1234567', -10, 10) from table_name;
The above query would always return 10 digits and add leading zeroes to the missed out number of digits.
For example, the above query would return : 0001234567
For Update, use
UPDATE TABLE_NAME SET PHONE_NO = substr('0000000000'|| PHONE_NO, -10, 10);
If you're sure that just prepending a zero on strings with length 9 will work for your application, something simple will work:
SELECT CASE WHEN LENGTH(phone_number) = 9 THEN '0'||phone_number
ELSE phone_number
END AS phone_number
FROM your_table
;
You could also update the table, depending on your needs:
UPDATE your_table
SET phone_number = '0'||phone_number
WHERE LENGTH(phone_number) = 9
;
Open the .csv using Excel,
Add a filter to the column,
Sort from A-Z to get all the columns with 9 digits,
Then follow the steps here
http://office.microsoft.com/en-au/excel-help/keep-leading-zeros-in-number-codes-HA010342581.aspx

Natural Sorting SQL ORDER BY

Can anyone lend me a hand as to what I should append to my ORDER BY statement to sort these values naturally:
1
10
2
22
20405-109
20405-101
20404-100
X
Z
D
Ideally I'd like something along the lines of:
1
2
10
22
20404-100
20405-101
20405-109
D
X
Z
I'm currently using:
ORDER BY t.property, l.unit_number
where the values are l.unit_number
I've tried doing l.unit_number * 1 and l.unit_number + 0 but they haven't worked.
Should I be doing sort of ORDER conditional, such as Case When IsNumeric(l.unit_number)?
Thank you.
This will do it:
SELECT value
FROM Table1
ORDER BY value REGEXP '^[A-Za-z]+$'
,CAST(value as SIGNED INTEGER)
,CAST(REPLACE(value,'-','')AS SIGNED INTEGER)
,value
The 4 levels of the ORDER BY:
REGEXP assigns any alpha line a 1 and non-alphas a 0
SIGNED INT Sorts all of the numbers by the portion preceding the dash.
SIGNED INT after removing the dash sorts any of the items with the same value before the dash by the portion after the dash. Potentially could replace number 2, but wouldn't want to treat 90-1 the same as 9-01 should the case arise.
Sorts the letters alphabetically.
Demo: SQL Fiddle

Need a help for sort in mysql

Hi I want to sort a table .The field contains numbers,alphabets and numbers with alphabets ie,
1
2
1a
11a
a
6a
b
I want to sort this to,
1
1a
2
6a
11a
a
b
My code is, SELECT * FROM t ORDER BY CAST(st AS SIGNED), st
But the result is,
a
b
1
1a
2
6a
11a
I found this code in this url "http://www.mpopp.net/2006/06/sorting-of-numeric-values-mixed-with-alphanumeric-values/"
Anyone please help me
This would do your required sort order, even in the presence of 0 in the table;
SELECT * FROM t
ORDER BY
st REGEXP '^[[:alpha:]].*',
st+0,
st
An SQLfiddle to test with.
As a first sort criteria, it sorts anything that starts with a letter after anything that doesn't. That's what the regexp does.
As a second sort criteria it sorts by the numerical value the string starts with (st+0 adds 0 to the numerical part the string starts with and returns an int)
As a last resort, it sorts by the string itself to get the alphabetical ones in order.
You can use this:
SELECT *
FROM t
ORDER BY
st+0=0, st+0, st
Using st+0 the varchar column will be casted to int. Ordering by st+0=0 will put alphanumeric rows at the bottom (st+0=0 will be 1 if the string starts with an alphanumeric character, oterwise it will be 0)
Please see fiddle here.
The reason that you are getting this output is that all the character like 'a', 'b' etc are converted to '0' and if you use order by ASC it will appear at the top.
SELECT CAST(number AS SIGNED) from tbl
is returning
1
2
1
11
0
6
0
Look at this fiddle:- SQL FIDDLE
I did small change in your query -
SELECT *, CAST(st AS SIGNED) as casted_column
FROM t
ORDER BY casted_column ASC, st ASC
this should work.
in theory your syntax should work but not sure why mysql doesn't accept these methods after from tag.
so created temp field and then sorted that one .
This should work as per my experience, and you can check it.
SQL FIDDLE

using regualr expression in mysql to select specific rows

I'm trying to select a small set of records that match a patten I have a series of numbers in each row such as
1
2
3
some of them have sub numbers
3.1
3.2
4
5
I can select only the whole numbers using
REGEXP '^[0-9]+$'
I can select all rows that have a . in them like 3.1 3.2 etc using
REGEXP '[.]{1}'
but I can't seem to select for example only sub numbers that start with 3 I've tried
REGEXP '[^3.]{1,}'
but that returns all records
Ideally I want to return only records that are in the format of 3.1 I would like to define the start number and the dot so 3. then the second part match against the records
I hope this makes sense
I used '3\.[0-9]{1,}' - it matched.
Yours probably fails because of unescaped dot - ., which matches every character.
Escape characters with \
Format 3.d where d is digit:
3\\.[0-9]