通过连接两个表

时间:2017-07-06 10:06:08

标签: sql sql-server casting nvarchar sql-convert

我需要在数据库中找到缺少的数字。我正在比较两个数据库,在查询中创建的tempdb与数字1 - 999和MYDAT。

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]%'

我收到错误&#34;将varchar转换为int&#34;但我不明白为什么。当我将左连接更改为右连接时,我没有错误。

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

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

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

编辑:

1 - 当我在rextester上尝试时,我看到一个错误。 I added MYDAT.ID IS NULL查询,以便我得到正确的结果。

2 - 例子 我需要这个:http://rextester.com/KFG73206

但CAST或CONVERT似乎不起作用http://rextester.com/WJIAH52304

3 个答案:

答案 0 :(得分:1)

你确实说过&#39;缺少数字&#39;因此,你在MYDAT中不属于tempdb的东西是你所追求的吗?如果是这样,请参阅:http://rextester.com/HCB88714

答案 1 :(得分: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]%'

答案 2 :(得分: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确保评估顺序。