简体   繁体   English

仅当条件为真时才进行SQL JOIN

[英]SQL JOIN only when a condition is true

I have 3 variables in my SQL stored procedure and want to add a join only if the 3rd variable is not null. 我的SQL存储过程中有3个变量,并且仅在第3个变量不为null时才想添加联接。

This is how i am trying to do it but it doesn't work. 这就是我正在尝试执行的操作,但是它不起作用。 It gives the following error on the line pointed out: 它在指出的行上给出以下错误:

Incorrect syntax near '{' '{'附近的语法不正确

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)

Couldn't you just use an and on the join? 您不能只在联接上使用and吗? The join will be attempted but if @three is null then no joins to synonym would occur.... or do you really need to ignore the join for performance reasons? 将尝试进行连接,但是如果@three为null,则不会发生对同义词的连接....还是出于性能原因您真的需要忽略该连接吗? if so Dynamic SQL is the only way I could see to make it work... 如果是这样的话,动态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)

This is not correct syntax, but you could do achieve this in few ways, the dumbest way to do is add the Boolean check on the top. 这不是正确的语法,但是您可以通过几种方法来实现,最愚蠢的方法是在顶部添加布尔检查。

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

Or you could use case..when to control, it does the same thing as multiple if 或者,您可以使用case..when进行控制时, if

You need to give that condition while joining itself. 您需要在加入自己时提供该条件。

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)

You can achieve this by building dynamic query like following 您可以通过构建动态查询来实现此目标,如下所示

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)

What about: 关于什么:

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)

replace IF @three with this : 将IF @three替换为:

 LEFT JOIN (select * from dbo.Synonym  where @three IS NOT NULL) as synm ON cinfo.ID = synm.ID

and verify ALTER procedure syntax and LIKE syntax. 并验证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)

Try to write Like IF @three IS NOT NULL ALTER PROCEDURE [dbo].[Search] @one NVARCHAR(50), @two NVARCHAR(50), @three NVARCHAR(50) 尝试写类似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)

end else ALTER PROCEDURE [dbo].[Search] @one NVARCHAR(50), @two NVARCHAR(50), @three NVARCHAR(50) 结束其他程序[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

end 结束

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM