将varchar值'T70001'转换为数据类型int时转换失败?

问题描述 投票:0回答:3

使用以下查询时,我收到上述错误

 SELECT  b.*,E.SSNO
  FROM [SRV-RVS].[dbo].[CARD] b
  INNER JOIN [SRV-RVS].dbo.EMP e
  on b.EMPID=E.SSNO 
  WHERE E.SSNO LIKE 't%' 

我正在尝试加入这两个表,这里我的EMPID与SSNO相同,但它在开头就有了一个字符。

希望你明白了

问候

sql join casting type-conversion inner-join
3个回答
1
投票

您可以将EMPID转换为varchar并在join子句中添加'T'字符。

SELECT  b.*,E.SNO
FROM [SRV-RVS].[dbo].[CARD] b INNER JOIN [SRV-RVS].dbo.EMP e ON ('T' + REPLACE(STR(CAST(b.EMPID as varchar(9)), 9), SPACE(1), '0')) = E.SSNO 
WHERE E.SNO LIKE 't%' 

补充说明

  • 我猜测varchar的长度,但SSN通常总是9位数。如果您在-列中存储像SSNO这样的掩码/空格字符,则此代码将不起作用。
  • 在那里有代码留下0填充SSN号码的id,以0开头作为int到字符串不会自动填充0。
  • 如果数据集很大,则可能会导致性能问题。
  • 实际上,架构永远不应该将SSN转换为int(数字)开头。它应该保留为varchar字段,理想情况下不会在另一个表上设置为主键。

再次(从上一个项目继续),更改架构或添加计算列。这是目前糟糕的设计。


1
投票

修复您的表,以便您可以进行连接。本答案的其余部分假定您使用的是SQL Server(基于问题中代码的语法)。

我鼓励你这样做:

alter table emp
    add column ssno as ( cast(stuff(empid, 1, 1, '') as int) );

或者任何类型匹配。你甚至可以建立一个索引。

那么你的代码就不必记住有关empidssno之间关系的业务规则。


1
投票

通过从字符串中提取数值来加入表,因此它将在Id列上匹配。它应该返回结果,因为你在dddd中有任何其他惊喜。这通过在开始时消除字符来起作用。

  SELECT  b.*,E.SSNO
  FROM [SRV-RVS].[dbo].[CARD] b
  INNER JOIN [SRV-RVS].dbo.EMP e
  on right(b.EMPID, len(b.EMPID) - (PatIndex('%[0-9]%', b.EMPID )-1) ) 
     =right(E.SSNO, len(E.SSNO) - (PatIndex('%[0-9]%', E.SSNO )-1) ) 
© www.soinside.com 2019 - 2024. All rights reserved.