2017-07-06 76 views
0

我需要在我的数据库中查找缺少的数字。我正在比较两个数据库,tempdb在查询中用数字1-999和MYDAT创建。通过连接两个表将varchar转换为int时出现SQL错误

MYDAT样子:

+-------+ 
| id | 
+-------+ 
| A-001 | 
| A-002 | 
| A-004 | 
| A-... | 
| A-952 | 
| A-... | 
+-------+ 

我运行此查询:

declare @tempid int 

set @tempid = 1 

create table tempdb (tempid int) 

while @tempid < 1000 
begin 
    insert into tempdb values(@tempid) 
    set @tempid = @tempid + 1 
end 

select tempdb.tempid from tempdb 
left join MYDAT on tempdb.tempid = CAST(SUBSTRING(MYDAT.ID, 3, 3) as INT) 
where 
MYDAT.ID IS NULL and 
SUBSTRING(MYDAT.ID, 3, 3) <> '' and 
SUBSTRING(MYDAT.ID, 3, 3) <> '000'and 
SUBSTRING(MYDAT.ID, 3, 3) NOT LIKE '%[^0-9]%' 

drop table tempdb 

没有滴速temdb,select * from tempdb看起来不错,我得到我想要的东西。

从MYDAT有选择和转换数据的部分做工不错,我只得到整数

select CAST(SUBSTRING(MYDAT.ID, 3, 3) as INT) fom MYDAT 
where 
SUBSTRING(MYDAT.ID, 3, 3) <> '' and 
SUBSTRING(MYDAT.ID, 3, 3) <> '000'and 
SUBSTRING(MYDAT.ID, 3, 3) NOT LIKE '%[^0-9]%' 

我得到一个错误“转换为varchar到int”但我不知道为什么。当我将左连接更改为右连接时,我没有收到任何错误。

我也手动检查了两个数据库,没有字符串或字符,只有整数。

我也尝试了CONVERT()但结果相同。

任何建议或想法是什么问题?

编辑:

1 - 我看到一个错误,因为我试图在rextester。 I added MYDAT.ID IS NULL查询,所以我得到正确的结果。

2 - 范例 我需要这样的:http://rextester.com/KFG73206

但CAST或CONVERT只是不似乎工作http://rextester.com/WJIAH52304

+0

标记您正在使用的dbms。 (有些产品特定的结构......) – jarlh

+0

这对我来说并不明显,为什么你会得到这个错误。你可以在[Rextester](http://www.rextester.com)为我们创建一个演示,并将链接粘贴到这里? –

+0

http://rextester.com/CSY70642我能想到的唯一的事情就是在MYDAT中的ID不是你的想法..因为这看起来像它的工作原理..如何在架构中定义ID类型,长度等。 – JGFMK

回答

1

你确实说'缺少数字',所以tempdb中不在MYDAT中的东西是你所追求的东西?如果是这样,请参阅:http://rextester.com/HCB88714

+0

NOT IN()......非常聪明......非常感谢你 – user2463808

0

不能清楚地说明原因,可能是数据的问题。你可以尝试一些解决办法,以避免铸造,

create table tempdb (tempid varchar(3)) 

while @tempid < 1000 
begin 
    insert into tempdb values(@tempid) 
    set @tempid = @tempid + 1 
end 

select tempdb.tempid from tempdb 
left join MYDAT on tempdb.tempid = SUBSTRING(MYDAT.ID, 3, 3) 
where 
SUBSTRING(MYDAT.ID, 3, 3) <> '' and 
SUBSTRING(MYDAT.ID, 3, 3) <> '000'and 
SUBSTRING(MYDAT.ID, 3, 3) NOT LIKE '%[^0-9]%' 
0

的问题是,where条款不一定on子句前执行。 SQL Server可以重新排列操作。

我想你真的想要比较MYDAT.ID的前三个字符。这简化了一些事情,因为您可以像下面的代码那样使用LEFT()。事实上,你的where条件看起来不正确,所以我修复了它们。

最好的解决办法是try_convert()

select tempdb.tempid 
from tempdb left join 
    MYDAT 
    on tempdb.tempid = try_convert(int, left(MYDAT.ID, 3)) 
where MYDAT.ID <> '' and 
     left(MYDAT.ID, 3) <> '000' and 
     left(MYDAT.ID, 3) NOT LIKE '%[^0-9]%'; 

在-SQL预Server 2012个的版本,你可以使用一个case代替:

select tempdb.tempid 
from tempdb left join 
    MYDAT 
    on tempdb.tempid = (case when left(MYDAT.ID, 1, 3) not like '%[^0-9]%') 
           then convert(int, left(MYDAT.ID, 3) 
         end) 
where MYDAT.ID <> '' and 
     left(MYDAT.ID, 3) <> '000' and 
     left(MYDAT.ID, 3) NOT LIKE '%[^0-9]%'; 

case不保证评价的顺序。

相关问题