2017-06-14 170 views
1

會有人能夠解釋爲什麼下面的查詢返回的結果集導致不同的結果:左連接與內部連接使用子串/左功能時

SELECT sub.*, xr.* 
FROM (
    select rc.CommentID, 
      [CreateDate] = LEFT(rc.Comments, 10), 
      [CreatedBy] = SUBSTRING(rc.Comments, 12, CHARINDEX(':', rc.Comments) - 12), 
      src.Comments 
    from dbo.RequestComments rc 
    where rc.CommentID NOT IN(4290, 4289, 4221) 
) sub 
LEFT JOIN dbo.SWDBCWUserXRef xr 
ON sub.CreatedBy = xr.EnteredByName 

...但是,如果我將它修改爲使用INNER JOIN代替LEFT JOIN:

SELECT sub.*, xr.* 
FROM (
    select rc.CommentID, 
      [CreateDate] = LEFT(rc.Comments, 10), 
      [CreatedBy] = SUBSTRING(rc.Comments, 12, CHARINDEX(':', rc.Comments) - 12), 
      src.Comments 
    from dbo.RequestComments rc 
    where rc.CommentID NOT IN(4290, 4289, 4221) 
) sub 
JOIN dbo.SWDBCWUserXRef xr 
ON sub.CreatedBy = xr.EnteredByName 

我收到以下錯誤:

Msg 537, Level 16, State 3, Line 3 
Invalid length parameter passed to the LEFT or SUBSTRING function. 

感謝。

+1

可能是因爲你在內部得到更多的記錄JOIN其中SUBSTRING ... CHARINDEX(...是生產負值。 – mjw

+1

我很難相信你做的,如果是這樣的完整的查詢爲什麼當你不使用common-table-expression時,你會標記common-table-expression?你能發佈一個腳本來重現問題嗎?最可能的解釋:問題出現在你沒有顯示的代碼的某些部分 –

+2

最有可能的是,編譯器首先處理連接,而不考慮NOT IN,導致一些CreatedBy爲NULL/-1等。也許考慮一個CTE(可能會做同樣的事情),或者一個子查詢的temptable/table變量。 –

回答

0
SELECT sub.*, xr.* 
FROM (
select rc.CommentID, 
[CreateDate] = LEFT(rc.Comments, 10), 
[CreatedBy] = SUBSTRING(rc.Comments, 12, CHARINDEX(':', rc.Comments) - 12), 
src.Comments 
from dbo.RequestComments rc 
where rc.CommentID NOT IN(4290, 4289, 4221) 
) sub 
JOIN dbo.SWDBCWUserXRef xr 
ON SUBSTRING(rc.Comments, 12, CHARINDEX(':', rc.Comments) = xr.EnteredByName