【问题标题】:Why my code doesn't work? (using multi expressions + cast + case)为什么我的代码不起作用? (使用多重表达式 + cast + case)
【发布时间】:2016-07-22 14:29:06
【问题描述】:

我的专栏例子:

          (name) as varchar(50)
              s01
              s02
              s16

我想使用 case 和 cast 来选择 0 以上的第一个缺失的面板名称(在我的示例中,所需的选择将是 's03')

WITH cte AS(
    SELECT name 
    FROM customers 
    UNION ALL 
    SELECT 0
) 

SELECT  CASE WHEN cast(min(right(name, 2) + 1) as varchar(50)) < 10 THEN 's0' ELSE 's' END + 
        cast(min(right(name, 2) + 1) as varchar(50)) 
FROM cte 
WHERE NOT EXISTS ( 
    SELECT name 
    FROM customers  
    WHERE cast(right(customers.name, 2) as varchar(50)) = cast(right(cte.name, 2) as varchar(50))+1) 

此代码有效,但仅适用于我的表为空或表仅包含数字的情况。

以 name 中的列为例-> 结果将是 s03

             1     or   101    
             2          102
             16         116

但是当它包含字母时

 example my columns in name
             s01         
             s02
             s016

它不起作用。我收到一个错误:将 varchar 值“s01”转换为数据类型 int 时转换失败。我应该把其他地方转换为 varchar 吗?

【问题讨论】:

  • 有什么建议吗?或者它更好地使用其他代码来做我想做的事?
  • 请编辑您的问题以将相关表格 DDL 和示例数据包含为 DML。
  • 我编辑我的问题更具体。有什么建议吗?
  • 我看到这个问题被标记为 Sql Server 2000。Sql Server 2000 已方式结束生命。它不再获得任何补丁,即使是针对关键的安全问题,并且现在已经有一段时间没有了。继续使用它是非常不负责任的。升级此服务器是工作 1。这也是您的代码无法正常工作的原因。直到 Sql Server 2005 才将 CTE 添加到 Sql Server。
  • 这并没有更好。 Sql Server 2005 现在也终止了(截至今年 4 月 12 日)。

标签: sql sql-server-2005


【解决方案1】:

(代表 OP 发布)

只需要转换联合选择。

    WITH cte AS(
    SELECT name 
    FROM customers 
    UNION ALL 
    SELECT CAST(0 AS VARCHAR(50)) 
    FROM INVENTORYPANELCAPTIONS
) 

SELECT  CASE WHEN  cast(min(right(name, 2) + 1) as varchar(50)) < 10 THEN 's0' ELSE 's' END 
        + cast(min(right(name, 2) + 1) as varchar(50)) 
FROM cte 
WHERE NOT EXISTS ( 
    SELECT name 
    FROM customers 
    WHERE right(customers.name, 2)= right(cte.name, 2)+1) 

【讨论】:

    【解决方案2】:

    您正在将字符串 (varchar) 与 int 值进行比较,因此在将 varchar 数字与 int 值进行比较或对其进行一些操作之前,请尝试将其转换为 int 而不是 varchar

    可能是这样的(不确定这是否可行,但只是将其作为解决方案的外观示例):

    WITH cte AS(SELECT panelname FROM inventorypanelcaptions UNION ALL SELECT 0) 
    SELECT CASE WHEN min(cast(right(panelname, 2) as int)) + 1 < 10 THEN 'o0' ELSE 'o' + cast(min(cast(right(panelname, 2) as int)) + 1 as varchar(50)) END
    FROM cte 
    WHERE NOT EXISTS (SELECT panelname FROM inventorypanelcaptions WHERE cast(right(inventorypanelcaptions.panelname, 2) as int) = cast(right(cte.panelname, 2) as int) + 1)
    

    【讨论】:

    • 感谢您的回答,但我遇到了同样的错误。请帮忙!
    • 我仍然遇到同样的错误:将 varchar 值 'o01' 转换为数据类型 int 时转换失败。
    • 同样的错误...我认为是在其他地方。你想参加私人聊天吗?
    • 不幸的是,我现在不能,因为我需要离开,但我可以稍后回来尝试,但请检查我在代码上方写的内容(关于将数字转换为 int),也许我在您的查询中遗漏了一些内容
    • 并尝试: SELECT right(panelname, 2) FROM inventorypanelcaptions ... 如果您不使用 varchar 或 nvarchar 作为数据类型,CAST 可能会出现问题,因为最后 2 个字符不必是在这种情况下的数字(我假设您使用的是 varchar 或 nvarchar 的 SQL 示例)
    猜你喜欢
    • 1970-01-01
    • 2018-04-01
    • 2022-01-20
    • 2012-11-17
    • 2010-09-05
    • 1970-01-01
    • 2014-01-23
    • 2013-08-06
    相关资源
    最近更新 更多