Sql server SQL Server-Ascend的订单似乎不起作用

Sql server SQL Server-Ascend的订单似乎不起作用,sql-server,tsql,sql-order-by,Sql Server,Tsql,Sql Order By,我有一个数据库为用户创建记录,他们可以创建这些记录的新版本。我跟踪旧记录,因此通过在数据库中添加一列(VARCHAR(20))来区分它,该列存储数据的版本。我创建了一个存储过程,它获取与用户ID匹配的行,并以字符串形式对版本进行排序,版本之间用“|”分隔。这已经运行了一段时间,但最近一个用户创建了第10个版本,不知怎么的,这个流程似乎中断了。以下是SP: DECLARE @IN_vsId VARCHAR(100) SET @IN_vsId='user1' SELECT @Version_str

我有一个数据库为用户创建记录,他们可以创建这些记录的新版本。我跟踪旧记录,因此通过在数据库中添加一列(VARCHAR(20))来区分它,该列存储数据的版本。我创建了一个存储过程,它获取与用户ID匹配的行,并以字符串形式对版本进行排序,版本之间用“|”分隔。这已经运行了一段时间,但最近一个用户创建了第10个版本,不知怎么的,这个流程似乎中断了。以下是SP:

DECLARE @IN_vsId VARCHAR(100)

SET @IN_vsId='user1'
SELECT @Version_str = COALESCE(@Version_str + '|', '') + VSN_NO 
FROM (
SELECT TOP 100 VSN_NO
FROM table1 myTable
WHERE myTable.ID = @IN_vsId
ORDER BY myTable.VSN_NO ASC
)VERSION_TBL

PRINT @Version_str

当用户在SQL中使用时,一个表表示一组无序的行。您需要一个
orderby
子句来对数据进行排序。对内部查询的结果进行排序并不重要。从外部查询的角度来看,内部查询返回的数据集就是:一组无序的行。您需要在外部查询中进行排序

另一个问题是,您似乎将数字存储为字符串。字符串排序规则与数字数据类型不同(通常,按字符串排序,
'2
大于
'10'
)。您可以在排序之前强制转换为数字数据类型:

SET @IN_vsId='user1'
SELECT @Version_str = COALESCE(@Version_str + '|', '') + VSN_NO 
FROM (
    SELECT TOP 100 VSN_NO
    FROM table1 myTable
    WHERE myTable.ID = @IN_vsId
    ORDER BY CAST(VSN_NO AS INT) ASC
) VERSION_TBL
ORDER BY CAST(VSN_NO AS INT) ASC
如果存在无法将某些值转换为数字的风险,您可以使用:

ORDER BY TRY_CAST(VSN_NO AS INT) ASC

问题是版本是
varchar
,而不是某种类型的数字。在这种情况下,将值添加为“1”、“2”、“10”等

对字符串排序时,首先比较第一个字符,然后比较第二个字符,以此类推。因此,按字母顺序排序时,这是正确的:

1
10
2
20
您需要将这些值填充为零:

01
02
10
20
或者,如果希望正确排序,请使用数字字段(int、numeric等)

现在,考虑到上面的新信息(有些代码以字母开头),任务变得更加复杂,但并非无法管理。请在ORDER BY语句中尝试此操作(假设数字前只有一个字母字符,但不假设某些代码不能同时包含字母和数字):


让我尝试在本地运行此命令。不幸的是,此命令仍然给出相同的响应,使用VSN\u NO ASC的
VERSION\u TBL ORDER
,即使使用
CAST
,这仍然是不正确的。如果超过100行,嵌套的
SELECT
还需要一个
ORDER BY
。@LaughingVergil:正确,它也需要ORDER BY,因此
前100个
是值得的。我添加了它。@GMB我们有一些版本预先固定了一个
P
来表示一个特殊的版本,它会破坏它吗?您也可以按(将mytable.VSN\u NO转换为int)订购ASC@pmbAustin同意,但效率较低。@pmbAustin让我试试看,最简单的更改是SP,而不是DB架构(企业用例)是的,它不会有效率,如果任何一个值不能转换为int,它可能会失败。但这是一个短期的黑客解决方案,直到一个真正的解决方案可以付诸实施。性能完全取决于结果集返回的行数。如果少于数百行,就可以了。如果超过数千行,可能就不会了。@Wergil I笑着说我想我找到了一个解决P问题的方法,当我测试它时,它似乎起了作用。让我把它放在我的问题中。这里的问题是将数字存储为字符串。将版本号存储为int,这个问题就会自行解决。@SeanLange理想情况下,我继承了这个DB模式,我不能再对列类型进行更改,哈我要用我得到的东西来工作:)
01
02
10
20
ORDER BY CASE
    When IsNumeric(VSN_NO) = 1
        THEN RIGHT('000000' + VSN_NO, 6) -- assumes a max of six characters
    ELSE Left(VSN_NO, 1) + RIGHT('00000' + SUBSTRING(VSN_NO, 2, LEN(VSN_NO)), 5)
END ASC