简体   繁体   中英

SQL ORDER BY dilemma with numbers

I have a table which holds a varchar datatype. It holds 128 characters max.

I'm trying to order it alphabetically, and it works out fine, except for one little thing.

When I try to save a mixture of numbers and letters, it returns the 'literal' alphabetical order, which means 11 comes first before 2.

I have read almost all of the answers in the internet, but they are all workarounds that cannot work specifically for my problem.

Examples of values I want to put in order

Apartment
House
Dog
Cat
18 years old
2 years old
1 year old

But I want it to look like this.

1 year old
2 years old
18 years old
Apartment
Cat
Dog
House

It spans on a large database and I can't just split the numerical values apart from the text ones.

Also users who can use the program can modify it with Alphanumeric characters.

Any suggestions about my problem? Thanks.

Here is something I tried in SQL Server. It's neither elegant nor fit for production, but it may give you an idea.

SELECT StringValue, 
    CAST(SUBSTRING(StringValue, StartPos, EndPos - StartPos) AS INT) AsNumber,
    SUBSTRING(StringValue, StartPos, EndPos - StartPos) NumberToken,
    SUBSTRING(StringValue, EndPos, 1000) Rest,
    StartPos, 
    EndPos
FROM    
    (SELECT 
        StringValue,
        PATINDEX('[0-9]%', StringValue) StartPos,
        PATINDEX('%[^0-9]%', StringValue) EndPos
    FROM 
        (SELECT 'abc123xyz' StringValue
        UNION SELECT '1abc'
        UNION SELECT '11abc'
        UNION SELECT '2abc'
        UNION SELECT '100 zasdfasd') Sub1
    ) Sub2
ORDER BY AsNumber, Rest

Result:

StringValue       AsNumber        NumberToken  Rest            StartPos     EndPos
abc123xyz                 0                    abc123xyz               0          1
1abc                      1                  1 abc                     1          2
2abc                      2                  2 abc                     1          2
11abc                    11                 11 abc                     1          3
100 zasdfasd            100                100  zasdfasd               1          4

I would approach this as follows...

First, write an expression to convert the numeric stuff to integers, something like

select CAST(SUBSTRING(<field>',1,instr(<field>',' ') as INT),<field>

I would then use a UNION ALL statement, something like this

SELECT CAST(SUBSTRING(<field>',1,instr(<field>',' ') as INT),<field>,A.*
FROM <table> A
WHERE <field> LIKE <regular expression to get fields beginning with numbers>
UNION ALL
SELECT 999999,<field>,A.*
FROM <table> A
WHERE <field> NOT LIKE <regular expression to get fields beginning with numbers>
ORDER BY 1,2,3

The numbers will appear first, in numeric order. Sine all of the alpha data has the same numeric key, it will appear sorted alphabetically after the numbers... Just be sure to make the alpha dummy key (999999) is large enough to be after all the numeric ones...

I don't have mySQL on this machine, but hopefully this gives you enough of a start to solve it

您应该通过执行以下操作来摆脱困境:

order by right(replicate(' ',30)+Column_name,30)

Try this order by:

ORDER BY RIGHT(REPLICATE('0',128)+value,128)

My test:

DECLARE @T TABLE
(
value VARCHAR(128)
)

INSERT INTO @T VALUES('Apartment'),
('House'),
('Dog'),
('Cat'),
('18 years old'),
('2 years old'),
('1 year old'),
('12 horses'),
('1 horse')


SELECT * FROM @T
ORDER BY RIGHT(REPLICATE('0',128)+value,128)

RESULTS:

Cat
Dog
House
1 horse
12 horses
Apartment
1 year old
2 years old
18 years old

If you find a case that this doesn't work please post it along with the sort order you would like and I can see if there's a fix.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM