我必须对同时包含字母和数字字符的产品名称的查询输出进行排序。
我已经找到了将变量转换为数值(+0等)的各种解决方案,它们对产品名称的数值部分进行排序。但产品名称字符串的前一部分长度不同,因此名称不是按字母顺序排序的:
Post Lantern PL1
Post Lantern PL2
Post Lantern PL10
Post Lantern PL22
Landscape Light LV1
Landscape Light LV2
Landscape Light LV10
Landscape Light LV11我想短的名字是先排序的吧?
我希望结果自然地排序:按字母顺序排序,数字也按自然顺序排序。我试过了:
ORDER by CAST(`product_name` AS DECIMAL), product_name
...
ORDER by product_name+0较短的名称首先排序,即使它们在字母表中排在后面。最后一部分中的数字需要按数字顺序排列。
发布于 2013-01-05 12:06:54
下面是一个很长的查询,它做了你想要的事情。不过,我对性能不太确定。您可能还想对几个记录进行一些测试,以确保。
SELECT
*
,SUBSTRING(
REVERSE(CAST(REVERSE(CONCAT(`product_name`,'8')) AS UNSIGNED)),1,
CHARACTER_LENGTH(
REVERSE(CAST(REVERSE(CONCAT(`product_name`,'8')) AS UNSIGNED))
)-1
) AS 'numericVal'
FROM `some_table`
ORDER BY
SUBSTRING(`product_name`,1,CHAR_LENGTH(`product_name`)-CHAR_LENGTH(`numericVal`)),
CAST(`numericVal` AS UNSIGNED INTEGER)CONCAT()函数中的8用于以零结尾的数字。否则,当您反转字符串"etc30“并解析其中的数字时,它将是3,而不是03。因此,反转它将再次生成3,而不是<代码>E11030<代码>E211。
您可以在CONCAT()函数中将这两个8更改为您喜欢的任何单个数字(零除外)。
编辑2个
这是一个细目。
# Example record "Post Lantern PL10"...
SELECT
*
,SUBSTRING( # 5a) substring of this is calculated
REVERSE( # 4) gets re-reversed into "108"
CAST( # 3) gets casted into an integer so "801" part is parsed
REVERSE( # 2) gets reversed: "801LP nretnaL tsoP"
CONCAT(`product_name`,'8') # 1) is concatenated with an 8: "Post Lantern PL108"
)
AS UNSIGNED)
),
1, # 5b) from the first character (index is 1 for this in SQL)
CHARACTER_LENGTH( # 5c) and the length is recalculated (steps 1-4 repeated)
REVERSE(
CAST(
REVERSE(
CONCAT(`product_name`,'8')
)
AS UNSIGNED)
)
)-1 # 5d1) minus 1 because at the beginning we appended an 8 and we
# 5d2) want to get rid of it now, so we're dropping the last digit
) AS 'numericVal'
FROM `some_table`
ORDER BY # 6) order by
SUBSTRING(`product_name`, # 7a) first, substring `product_name`
1, # 7b) from the first character
CHAR_LENGTH(`product_name`)-CHAR_LENGTH(`numericVal`) # 7c) with the total length - length of numeric part
),
CAST(`numericVal` AS UNSIGNED INTEGER) # 8a) then, by the numeric part, which gets casted into
# 8b) an integer for accurate numeric ordering编辑1个
我认为最好的方法(完全控制不同的数据)是把product_name分成3列-- product_name (像“景观之光”),product_class (或者其他什么,像"LV")和product_version (数字部分)。
https://stackoverflow.com/questions/14167585
复制相似问题