Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用SQL Server尝试通过将子字符串强制转换为INT来执行订单_Sql_Sql Server_Casting_Sql Order By_Substring - Fatal编程技术网

使用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:

  • 如果组件数量可变,则
    parsename
    hack将不起作用-建议您查看将UDF拆分到db的组件
  • 从理智和枯燥的角度来看,您可能不想一步完成所有这一切—当您将一个数据转换的输出传递到下一个数据转换时,CTE将使您的生活更加轻松
  • 您可以尝试下面这样的填充技术,尝试解决数字/非数字混合排序问题。但是,为了适应字母后缀,我猜测填充需要同时位于原始值的左侧和右侧,而右侧填充保留给右侧填充的非数字后缀
  • 您可以使用
    顺序按情况进行条件排序,当…然后…否则…结束
    ,但请注意,所有分支都必须
填充想法“目标”的示例:

xxx1x
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;