【问题标题】:how to sort alphanumeric data in sql..?如何在 sql.. 中对字母数字数据进行排序?
【发布时间】:2015-06-18 17:58:15
【问题描述】:

我的项目表的大小如下:

1sq.mm.
1.5sq.mm.
0.5sq.mm.
2.5sq.mm.
0.75sq.mm.
4sq.mm.
20mm
25mm
20mtr
75mm x 50mm
100mm x 50mm
100mm x 100mm
75mm x 75mm

我想显示它有

0.5sq.mm.
0.75sq.mm.
1.5sq.mm.
2.5sq.mm.
4sq.mm.
20mm
20mtr
25mm
75mm x 50mm
75mm x 75mm
100mm x 50mm
100mm x 100mm

我尝试了以下 sql 查询,但出现错误

'Conversion failed when converting the varchar value '1 sq.mm.' to data type int.'

SQL查询:

  select * from Items 
  order by CAST(SUBSTRING(Sizes, PATINDEX('%[0-9]%', Sizes), LEN(Sizes)) AS INT)

【问题讨论】:

  • 一切都是平方毫米吗?如果不是,您如何根据单位定义订单?
  • Alphanumeric Sort 的可能重复项
  • @Supreethsup:由于这些字符串是大小列的一部分,我猜它们是大小单位,这意味着0.5sq.mm 可能与0.5pcs 不同。将数据分解为 numeric 和 varchar 值相当容易,但根据不同的单位计算正确的顺序可能有点棘手。顺便说一句,您永远不应该保留这样的混合数据。如果可能,请将大小和单位分开到不同的列中。
  • @ZoharPeled 重申 Zohar 所说的话,如果可能的话,有两列,大小和单位。
  • 20sq.mm 更大。还是20毫米?这是两个完全不同的维度。

标签: sql sql-server sql-server-2008 sql-server-2012


【解决方案1】:

ORDER BY 中使用REPLACE

SELECT Sizes
FROM Items
ORDER BY CAST(REPLACE(Sizes,'sq.mm.','') as NUMERIC(9,2))

输出:

Sizes
0.5sq.mm.
0.75sq.mm.
1sq.mm.
1.5sq.mm.
2.5sq.mm.
4sq.mm.

SQL 小提琴:http://sqlfiddle.com/#!3/ad91f/3/0

【讨论】:

  • 如果我没记错的话,留下 sq.m (因为它在所有条目中都一样)应该不会影响排序。
  • 没有REPLACE int 他ORDER BY 它不会以正确的顺序出现
  • @apomene: 1sq.mm1.5sq.mm 会出现问题。1.5sq.mm 将在 1sq.mm 之前。
  • 您缺少CASTnumeric 的顺序。如果没有演员表,它会进行字符串比较。 sqlfiddle.com/#!3/ad91f/3
  • 嗨@Matt 感谢您的解决方案它有效,但我有一个场景,其中尺寸不仅包含'sq.mm',它还包含'mtr','pcs' 在这种情况下有什么方法可以替换大小列中的任何字母
【解决方案2】:

试试这个:

SELECT Sizes       
FROM Items
ORDER BY CAST(LEFT(Sizes, PATINDEX('%[a-z]%', Sizes)-1) as numeric(9, 2))

假设您的数据始终是数字,后跟至少一个字母字符。

sql fiddle (thanks to matt!)

【讨论】:

  • 很高兴能提供帮助,大部分工作都由马特完成...我已经赞成他的回答,你应该感谢他,而不是我 :-)
【解决方案3】:
CREATE FUNCTION udf_GetNumeric
(@strAlphaNumeric VARCHAR(256))
RETURNS VARCHAR(256)
AS
BEGIN
DECLARE @intAlpha INT
SET @intAlpha = PATINDEX('%[^0-9]%', @strAlphaNumeric)
BEGIN
WHILE @intAlpha > 0
BEGIN
SET @strAlphaNumeric = STUFF(@strAlphaNumeric, @intAlpha, 1, '' )
SET @intAlpha = PATINDEX('%[^0-9]%', @strAlphaNumeric )
END
END
RETURN ISNULL(@strAlphaNumeric,0)
END
GO

SELECT dbo.udf_GetNumeric('sada322sds232132132');

drop function udf_GetNumeric;



Result
322232132132



CAST(dbo.udf_GetNumeric(Sizes) AS INT)

【讨论】:

  • 请不要只回答代码问题。解释你为什么这样做,以及错误在哪里。谢谢。
【解决方案4】:

只是一个建议 - 不是答案:

如果可能的话,我会重新考虑以不同的方式设计桌子。 目前,您正在对包含两种不同类型信息的列进行排序:长度 (mm) 和面积 (sq.mm),这没什么意义。

也许你更喜欢这样的数据结构:

CREATE TABLE MyTable(
  length decimal(5,2),
  width decimal(5,2),
  area decimal(10,2),
  unit varchar(10)
)

不用说,使用这种设计,排序会非常简单。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-17
    • 1970-01-01
    • 1970-01-01
    • 2011-02-06
    • 2018-07-29
    • 1970-01-01
    • 2011-07-25
    • 1970-01-01
    相关资源
    最近更新 更多