2017-07-06 94 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不保證評價的順序。

相關問題