我需要在数据库中找到缺少的数字。我正在比较两个数据库,在查询中创建的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
答案 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
确保评估顺序。