使用SQL Server尝试通过将子字符串强制转换为INT来执行订单
我的数据库中有一个字符串列,字段是数字和破折号的混合体。示例使用SQL Server尝试通过将子字符串强制转换为INT来执行订单,sql,sql-server,casting,sql-order-by,substring,Sql,Sql Server,Casting,Sql Order By,Substring,我的数据库中有一个字符串列,字段是数字和破折号的混合体。示例24-2548-25 由于填充问题,我想按整数的中心集合进行排序,例如24-25-25和24-1111-25不按数字排序,而是按字母排序 我想我需要像下面这样的东西,但语法甚至不接近正确 SELECT tblDrawings.* FROM tblDrawings WHERE (((tblDrawings.AreaNo) = "21")) ORDER BY SET @DashInt = PAT
24-2548-25
由于填充问题,我想按整数的中心集合进行排序,例如24-25-25
和24-1111-25
不按数字排序,而是按字母排序
我想我需要像下面这样的东西,但语法甚至不接近正确
SELECT
tblDrawings.*
FROM
tblDrawings
WHERE
(((tblDrawings.AreaNo) = "21"))
ORDER BY
SET @DashInt = PATINDEX('%-%', tblDrawings.DrawingNo);
SET @SecondDashInt = CHARINDEX('-',tblDrawings.DrawingNo,@DashInt + 1)
IF @DashInt > 0{CAST(SUBSTRING(tblDrawings.DrawingNo , IF @SecondDashInt > 0 {@DashInt + 1 ,@SecondDashInt} ELSE {LEN(tblDrawings.DrawingNo)} AS INT))} ELSE {DrawingNo};
如果图纸编号始终由3部分组成,并且假设您只想按中间部分数字升序进行排序,则可以(ab)使用
PARSENAME
函数加速拆分编号的组成部分(虚线需要替换为点,以诱使函数认为它是一个完全限定的名称):
(Parsename最多只能处理4个部件,并且从右到左排序)
编辑
在最终确定查询之前,您可能必须分析所有数据并确定所需的确切顺序。一些想法,FWIW:
- 如果组件数量可变,则
hack将不起作用-建议您查看将UDF拆分到db的组件parsename
- 从理智和枯燥的角度来看,您可能不想一步完成所有这一切—当您将一个数据转换的输出传递到下一个数据转换时,CTE将使您的生活更加轻松
- 您可以尝试下面这样的填充技术,尝试解决数字/非数字混合排序问题。但是,为了适应字母后缀,我猜测填充需要同时位于原始值的左侧和右侧,而右侧填充保留给右侧填充的非数字后缀
- 您可以使用
,但请注意,所有分支都必须顺序按情况进行条件排序,当…然后…否则…结束
xx11x
x111x
x111A
x112x
“12-”和“1”中复制的x的数量需要进行调整,以计算数字和非数字字符的数量,然后在前后调整填充。因此,使用另一个查询嵌套/cte可能需要计算拆分组件中的字符数量。Yakshemash。您能否提供更多信息-此表中的行数-固定/增加,1000s/数百万?另外,你只想按两个破折号之间的数字排序吗?@Borat 100s,它将缓慢增加,并且由于使用情况的原因,将有一个软限制。我想说它不会超过2000。不幸的是,数据并不总是有两个破折号,也不一定只有数字。有时,一个破折号可能会出现er是在数字集的末尾输入的。我试图用If语句在上面的代码中构建一些可变性。如果可能的话,我希望它排序为###-$$-%%%(不是常量,而是最可能的格式)。其中#先排序,然后是$,最后是%。我想我在一个不均匀的数据集中要求了很多…我的另一个选择是将整个结果转储到代码中,然后在遍历行时对其进行排序以解决问题。将其放回临时表,然后根据新表进行选择。这似乎不是最好的选择。(我使用VBS在ASP中编写代码,别笑,这是一项增强工作)。我喜欢这个想法,并会加以利用,但不幸的是,有些想法没有两个破折号。而且也不能保证它只限于数字。我希望像我在上面代码中使用的那样,使用IF语句使其具有一定的灵活性。我甚至不确定是否可以像我试图做的那样按顺序使用IF语句。@Mobile_Bob我想我从你在OP中的例子中推断出,破折号的数量是恒定的,第二个部分是数字。我已经更新了一些想法,但要让它100%工作,可能需要一个相当迭代的过程。祝你好运!
SELECT
tblDrawings.*
FROM
tblDrawings
WHERE
(((tblDrawings.AreaNo) = "21"))
ORDER BY CAST(PARSENAME(REPLACE(DrawingNo, '-', '.'), 2) AS BIGINT) ASC;
WITH cte as
(
SELECT
*,
PARSENAME(REPLACE(DrawingNo, '-', '.'), 3) as [3FromRight],
PARSENAME(REPLACE(DrawingNo, '-', '.'), 2) as [2FromRight],
PARSENAME(REPLACE(DrawingNo, '-', '.'), 1) as [1FromRight]
FROM tblDrawings
)
SELECT *
FROM cte
ORDER BY
REPLICATE('x',12-LEN([2FromRight])) + [2FromRight] + REPLICATE('x', 1)
ASC;