我如何在sql中使用nvarchar列时接受订单

时间:2019-06-20 05:41:29

标签: sql sql-server string sql-order-by

我有这样的查询:

SELECT [Drug_id]
FROM tbl_Receiving
ORDER BY CAST(SUBSTRING([Drug_id], 3, LEN([Drug_ID])) as int)

但是结果越来越

A-1
A-10A
A-11
A-2
A-20A
A-21
A-22
A-3
A-30
A-31

但是我需要获得所有适当的升序。

   A-1
   A-2
   A-3
   A-10
   A-11

我的[Drug_id]列为nvarchar(50)

5 个答案:

答案 0 :(得分:0)

假设您的格式始终为A-<NUMBER>,则可以始终执行以下操作:

SELECT 
    [Drug_id]
FROM 
    tbl_Receiving
ORDER BY 
    CAST(SUBSTRING([Drug_id], 3, LEN([Drug_ID])) as int)

这将仅尝试从数字开始以int的形式进行投射

输出如下:

enter image description here

答案 1 :(得分:0)

如果定义的字符串格式如示例数据中所示,则可以使用SUBSTRING和CHARINDEX在(-)之前拆分字符串,在(-)之后拆分INT值。然后,您可以对它们应用订购以获取所需数据。

注意:当然,这些String操作存在性能问题。

SELECT *
FROM your_tabele
ORDER BY SUBSTRING(val,1,CHARINDEX('-',Val,1)-1),
CAST(SUBSTRING(val,CHARINDEX('-',Val,1)+1,LEN(val)-CHARINDEX('-',Val,1)) AS INT)

答案 2 :(得分:0)

尝试一下: 运行此查询

df$cumsum<-rowSums(df[,2:5]==c(1,2,3),na.rm=TRUE)
df
  ID cond1 cond2 cond3 cond4 cumsum
1  a     2     7     6     6      0
2  b     7     2     3     6      1
3  c     4     3     1     4      1
4  d     7     3     3     6      1
5  e     6     7     7     3      0

答案 3 :(得分:0)

我基本上已经从以下答案中复制了此内容:https://stackoverflow.com/a/16667778/9101689

它使用patindex来标识数字值的位置,并从实际值中子字符串化。我们使用该子字符串,并使用LEFT函数将所有内容修剪到右侧,并将该值转换为要排序的整数。

declare @d table (drug_id nvarchar(max))
insert into @d values ('A-1'),('A-10A'),('A-11'),('A-2'),('A-20A'),('A-21'),('A-22'),('A-3'),('A-30'),('A-31')
SELECT *
FROM (
    SELECT ORD_subsrt = SUBSTRING(drug_id, ORD_pos, LEN(drug_id)), *
    FROM (
        SELECT ORD_pos = PATINDEX('%[0-9]%', drug_id), *
        FROM @d
    ) d
) t
Order by cast(LEFT(ORD_subsrt, PATINDEX('%[^0-9]%', ORD_subsrt + 't') - 1) as int)

添加了值t,以便在drug_id字段中没有非数字后缀的情况下,patindex'%[^ 0-9]%'将返回非零值。

或更不可读:

SELECT *
From @d
Order by cast(LEFT(SUBSTRING(drug_id, PATINDEX('%[0-9]%', drug_id), LEN(drug_id)), PATINDEX('%[^0-9]%', SUBSTRING(drug_id, PATINDEX('%[0-9]%', drug_id), LEN(drug_id)) + 't') - 1) as int)

但是,如果您具有“ A2-10A”之类的值(或具有多个以上数值的任何内容),则此方法将无法正常工作。

答案 4 :(得分:0)

如果您的值始终采用以下形式:

<letter>-<number><optional letter>

然后,您可以执行以下操作:

order by (case when drug_id like '%[A-Z]'
               then len(drug_id) - 1  -- ignore the last character
               else len(drug_id)
          end)
         drug_id

这将drug_id视为字符串,使用长度来控制数字的顺序。在以下情况下有效:

  • 数字是整数
  • 数字不是非零填充
  • 前缀为固定长度