![](/img/trans.png)
[英]SQL Query: How to check for the Join condition in ON clause only if a condition is true
[英]SQL JOIN only when a condition is true
我的SQL存儲過程中有3個變量,並且僅在第3個變量不為null時才想添加聯接。
這就是我正在嘗試執行的操作,但是它不起作用。 它在指出的行上給出以下錯誤:
'{'附近的語法不正確
ALTER PROCEDURE [dbo].[Search]
@one NVARCHAR(50), @two NVARCHAR(50), @three NVARCHAR(50)
SELECT cinfo.ID,
cinfo.Nam,
cinfo.INAM,
cinfo.CA,
cinfo.Form,
cinfo.Std,
cval.Prop,
cval.Cons,
sc.Accep
From dbo.Info AS cinfo
Inner JOIN dbo.values AS cval
ON cinfo.ID = cval.ID
INNER JOIN dbo.Sources AS sc
ON (cval.sID = sc.sID AND sc.Accept = 'A')
IF @three IS NOT NULL{ **<---------------------**
LEFT JOIN dbo.Synonym AS synm
ON cinfo.ID = synm.ID}
where (cinfo.NAM LIKE '%'+@one+'%' OR cinfo.CAS LIKE '%'+@two+'%' OR
synm.SynonymID LIKE '%'+@three+'%') AND
(cval.PropID = '1' OR
cval.PropID = '2' OR
cval.PropID = '3' OR
cval.PropID = '4' OR)
您不能只在聯接上使用and
嗎? 將嘗試進行連接,但是如果@three為null,則不會發生對同義詞的連接....還是出於性能原因您真的需要忽略該連接嗎? 如果是這樣的話,動態SQL是我可以看到的唯一使它工作的方法...
ALTER PROCEDURE [dbo].[Search]
@one NVARCHAR(50), @two NVARCHAR(50), @three NVARCHAR(50)
SELECT cinfo.ID,
cinfo.Nam,
cinfo.INAM,
cinfo.CA,
cinfo.Form,
cinfo.Std,
cval.Prop,
cval.Cons,
sc.Accep
From dbo.Info AS cinfo
Inner JOIN dbo.values AS cval
ON cinfo.ID = cval.ID
INNER JOIN dbo.Sources AS sc
ON (cval.sID = sc.sID AND sc.Accept = 'A')
LEFT JOIN dbo.Synonym AS synm
ON cinfo.ID = synm.ID
and @three IS NOT NULL **<---------------------**
where (cinfo.NAM LIKE '%'+@one+'%' OR cinfo.CAS LIKE '%'+@two+'%' OR
synm.SynonymID LIKE '%'+@three+'%') AND
(cval.PropID = '1' OR
cval.PropID = '2' OR
cval.PropID = '3' OR
cval.PropID = '4' OR)
這不是正確的語法,但是您可以通過幾種方法來實現,最愚蠢的方法是在頂部添加布爾檢查。
IF @three IS NOT NULL
BEGIN
--FULL QUERY that JOIN dbo.Synonym
END
IF @Three IS NULL
BEGIN
--FULL QUERY that does not JOIN dbo.Synonym
END
或者,您可以使用case..when
進行控制時, if
您需要在加入自己時提供該條件。
ALTER PROCEDURE [dbo].[Search]
@one NVARCHAR(50), @two NVARCHAR(50), @three NVARCHAR(50)
SELECT cinfo.ID,
cinfo.Nam,
cinfo.INAM,
cinfo.CA,
cinfo.Form,
cinfo.Std,
cval.Prop,
cval.Cons,
sc.Accep
From dbo.Info AS cinfo
Inner JOIN dbo.values AS cval
ON cinfo.ID = cval.ID
INNER JOIN dbo.Sources AS sc
ON (cval.sID = sc.sID AND sc.Accept = 'A')
LEFT JOIN dbo.Synonym AS synm
ON (cinfo.ID = synm.ID and @three is not null) **<---------------------**
where (cinfo.NAM LIKE '%'+@one+'%' OR cinfo.CAS LIKE '%'+@two+'%' OR
synm.SynonymID LIKE '%'+@three+'%') AND
(cval.PropID = '1' OR
cval.PropID = '2' OR
cval.PropID = '3' OR
cval.PropID = '4' OR)
您可以通過構建動態查詢來實現此目標,如下所示
ALTER PROCEDURE [dbo].[Search]
@one NVARCHAR(50), @two NVARCHAR(50), @three NVARCHAR(50)
DECLARE @query varchar(2000)=' SELECT cinfo.ID,
cinfo.Nam,
cinfo.INAM,
cinfo.CA,
cinfo.Form,
cinfo.Std,
cval.Prop,
cval.Cons,
sc.Accep
From dbo.Info AS cinfo Inner JOIN dbo.values AS cval ON cinfo.ID = cval.ID
INNER JOIN dbo.Sources AS sc ON (cval.sID = sc.sID AND sc.Accept = ''A'')'
IF @three IS NOT NULL
BEGIN
SET @query = @query + ' LEFT JOIN dbo.Synonym AS synm ON cinfo.ID = synm.ID '
END
SET @query = @query + 'where (cinfo.NAM LIKE ''%' + @one + '%'' OR cinfo.CAS LIKE ''%' + @two + '%'' OR
synm.SynonymID LIKE ''%' + @three + '%'') AND
(cval.PropID = ''1'' OR
cval.PropID = ''2'' OR
cval.PropID = ''3'' OR
cval.PropID = ''4'')'
EXEC(@query)
關於什么:
ALTER PROCEDURE [dbo].[Search]
@one NVARCHAR(50), @two NVARCHAR(50), @three NVARCHAR(50)
SELECT cinfo.ID,
cinfo.Nam,
cinfo.INAM,
cinfo.CA,
cinfo.Form,
cinfo.Std,
cval.Prop,
cval.Cons,
sc.Accep
From dbo.Info AS cinfo
Inner JOIN dbo.values AS cval
ON cinfo.ID = cval.ID
INNER JOIN dbo.Sources AS sc
ON (cval.sID = sc.sID AND sc.Accept = 'A')
LEFT JOIN dbo.Synonym AS synm
ON (cinfo.ID = synm.ID AND @three IS NOT NULL)
where (cinfo.NAM LIKE '%'+@one+'%' OR cinfo.CAS LIKE '%'+@two+'%' OR
synm.SynonymID LIKE '%'+@three+'%') AND
(cval.PropID = '1' OR
cval.PropID = '2' OR
cval.PropID = '3' OR
cval.PropID = '4' OR)
將IF @three替換為:
LEFT JOIN (select * from dbo.Synonym where @three IS NOT NULL) as synm ON cinfo.ID = synm.ID
並驗證ALTER過程語法和LIKE語法。
You cannot use { for if condition just remove '{'
ALTER PROCEDURE [dbo].[Search]
@one NVARCHAR(50), @two NVARCHAR(50), @three NVARCHAR(50)
SELECT cinfo.ID,
cinfo.Nam,
cinfo.INAM,
cinfo.CA,
cinfo.Form,
cinfo.Std,
cval.Prop,
cval.Cons,
sc.Accep
From dbo.Info AS cinfo
Inner JOIN dbo.values AS cval
ON cinfo.ID = cval.ID
INNER JOIN dbo.Sources AS sc
ON (cval.sID = sc.sID AND sc.Accept = 'A')
**IF @three IS NOT NULL** Remove this line
LEFT JOIN dbo.Synonym AS synm
ON cinfo.ID = synm.ID}
where (cinfo.NAM LIKE '%'+@one+'%' OR cinfo.CAS LIKE '%'+@two+'%' OR
synm.SynonymID LIKE '%'+@three+'%') AND
(cval.PropID = '1' OR
cval.PropID = '2' OR
cval.PropID = '3' OR
cval.PropID = '4' OR)
嘗試寫類似IF @@ three is not NULL ALTER PROCEDURE [dbo]。[搜索] @one NVARCHAR(50),@ two NVARCHAR(50),@ three NVARCHAR(50)
SELECT cinfo.ID,
cinfo.Nam,
cinfo.INAM,
cinfo.CA,
cinfo.Form,
cinfo.Std,
cval.Prop,
cval.Cons,
sc.Accep
From dbo.Info AS cinfo
Inner JOIN dbo.values AS cval
ON cinfo.ID = cval.ID
INNER JOIN dbo.Sources AS sc
ON (cval.sID = sc.sID AND sc.Accept = 'A')
where (cinfo.NAM LIKE '%'+@one+'%' OR cinfo.CAS LIKE '%'+@two+'%' OR
synm.SynonymID LIKE '%'+@three+'%') AND
(cval.PropID = '1' OR
cval.PropID = '2' OR
cval.PropID = '3' OR
cval.PropID = '4' OR)
結束其他程序[dbo]。[搜索] @one NVARCHAR(50),@ two NVARCHAR(50),@ three NVARCHAR(50)
SELECT cinfo.ID,
cinfo.Nam,
cinfo.INAM,
cinfo.CA,
cinfo.Form,
cinfo.Std,
cval.Prop,
cval.Cons,
sc.Accep
From dbo.Info AS cinfo
Inner JOIN dbo.values AS cval
ON cinfo.ID = cval.ID
INNER JOIN dbo.Sources AS sc
ON (cval.sID = sc.sID AND sc.Accept = 'A')
LEFT JOIN dbo.Synonym AS synm
ON cinfo.ID = synm.ID}
where (cinfo.NAM LIKE '%'+@one+'%' OR cinfo.CAS LIKE '%'+@two+'%' OR
synm.SynonymID LIKE '%'+@three+'%') AND
(cval.PropID = '1' OR
cval.PropID = '2' OR
cval.PropID = '3' OR
cval.PropID = '4' OR).. rest code
結束
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.