2014-09-04 182 views
1

我有两个表我试图加入到一个特定的列(两者之间共享)。这些列中的数据应该表示数字,但数据实际上是字符,并且其中一些值是非数字的(例如'2,3,4'或'n/a')。我忽略了具有此列的非数字值的行。我治疗的列数字的加入,因为“001”必须匹配“1”,“01”,“0001”等内加入他们的作品,左外加入他们并不:奇数左连接错误

SELECT * 
FROM Table1 T1 
INNER JOIN Table2 T2 
    ON T1.ID NOT LIKE '%[^ 0-9]%' 
    AND T2.ID NOT LIKE '%[^ 0-9]%' 
    AND T1.ID + 0 = T2.ID + 0 
-- Success! 

SELECT * 
FROM Table1 T1 
LEFT JOIN Table2 T2 
    ON T1.ID NOT LIKE '%[^ 0-9]%' 
    AND T2.ID NOT LIKE '%[^ 0-9]%' 
    AND T1.ID + 0 = T2.ID + 0 
-- Conversion failed when converting the nvarchar value '2,3,4' to data type int. 

为什么我在外部连接上发生错误,而不是内部连接?

P.S .:修复数据是不是选项。这不是我的数据;我无法触摸它。我必须找到一个方法来处理它。

编辑:我正在运行SQL Server 2008 R2 RTM

+1

所以要清楚,你会得到一个错误?或者你没有得到你期望的数据?如果您收到错误,错误是什么? – 2014-09-04 17:29:52

+0

'T1.ID + 0 = T2.ID + 0'应该做什么?为什么不简单地'T1.ID = T2.ID'? – wdosanjos 2014-09-04 17:37:38

+0

你在查询中忘记了“外层”。 SELECT * FROM Table1 T1 LEFT Outer JOIN Table2 T2 on ... – 2014-09-04 17:39:29

回答

2

SQL Server不保证条件的评估顺序。在你的情况下,在NOT LIKE条件之前正在评估T1.ID + 0 = T2.ID + 0

请尝试以下方法(SQL 2012及以上):

SELECT * 
FROM Table1 T1 
LEFT JOIN Table2 T2 
    ON TRY_CAST(T1.ID AS int) = TRY_CAST(T2.ID AS int) 

SQL 2008:

SELECT * 
FROM (SELECT * FROM Table1 WHERE ID NOT LIKE '%[^ 0-9]%') T1 
LEFT JOIN (SELECT * FROM Table2 WHERE ID NOT LIKE '%[^ 0-9]%') T2 
    ON CAST(T1.ID AS INT) = CAST(T2.ID AS INT) 

参考

+0

在我的实际查询中,两端都有通配符('%');当我编写示例时,我没有添加它们。现在已经修复了。我检查了我的版本,我正在使用SQL Server 2008 :( – 2014-09-04 17:45:20

+0

感谢您的实际答案(顺序不能保证)和解决方案。您的SQL 2008解决方案适用于我的应用程序,在表1中增加了'OR ID IS NULL' )。 – 2014-09-04 17:56:43

1

如果您尝试这样做,而不是?它做你想做的事吗?

SELECT * 
FROM Table1 T1 
LEFT JOIN Table2 T2 
    ON (isnumeric(T1.ID) = 1 
     AND isnumeric(T2.ID) = 1) 
     AND try_parse(T1.ID as int) + 0 = try_parse(T2.ID as int) + 0 
+0

ISNUMERIC使两个查询都失败了,我想是因为它认为逗号是有效的。无论哪种方式,这可能会奏效,但我没有访问TRY_PARSE。 – 2014-09-04 17:51:40