Tsql 基于参数值的SQL条件连接

Tsql 基于参数值的SQL条件连接,tsql,function,stored-procedures,join,conditional,Tsql,Function,Stored Procedures,Join,Conditional,我需要基于存储过程中的参数值进行内部联接。我还使用一个函数将值从逗号分隔的值字符串中分割出来。我的代码如下 Select * from view_Project as vp join inline_split_me(@earmark) as e on (vp.EarmarkId LIKE e.Value and @earmark IS NOT NULL) 如果@earmark为NULL,则我根本不希望发生此联接,否则,如果我有字符串“%”或“119”或“119120121”,则应发生此联接并产

我需要基于存储过程中的参数值进行内部联接。我还使用一个函数将值从逗号分隔的值字符串中分割出来。我的代码如下

Select *
from view_Project as vp
join inline_split_me(@earmark) as e on (vp.EarmarkId LIKE e.Value and @earmark IS NOT NULL)
如果@earmark为NULL,则我根本不希望发生此联接,否则,如果我有字符串“%”或“119”或“119120121”,则应发生此联接并产生正确的结果。如果@earmark为null,我希望它根本不会发生,我想我可以使用and@earmark is not null来描述它,但是它没有返回正确的结果,这是通过注释连接行并运行与@earmark参数相同的存储过程发现的,该存储过程使用null作为@earmark参数,结果为我提供了所有行。当我保持这个连接并传递null时,我没有得到任何行,我已经处理这个问题有一段时间了,任何帮助都将不胜感激

以下是函数:

[inline_split_me](@param nvarchar(MAX))
RETURNS TABLE AS
RETURN(SELECT ltrim(rtrim(convert(nvarchar(4000),
    substring(@param, Number,
        charindex(N',' COLLATE SQL_Latin1_General_CP1_CI_AS,
        @param + convert(nvarchar(MAX), N','),
    Number) -
Number)
))) AS Value
   FROM   APM_Numbers
   WHERE  Number <= convert(int, len(@param))
     AND  substring(convert(nvarchar(MAX), N',') + @param, Number, 1) =
                    N',' COLLATE SQL_Latin1_General_CP1_CI_AS)

内部连接是你的问题。左连接将始终返回左侧的行,即使@earmark为NULL,连接条件也永远不会为true

Select *
from view_Project as vp
LEFT join inline_split_me(@earmark) as e on (vp.EarmarkId LIKE e.Value and @earmark IS NOT NULL)
当@earmark为NULL时,您可以使用联合来制造要连接的行

Select *
from view_Project as vp
INNER join (
    SELECT Value, -- columns here ...
    FROM inline_split_me(@earmark) as e
    UNION ALL
    SELECT DISTINCT vp.EarmarkId AS Value, -- NULL, NULL, etc.
    FROM view_Project
    WHERE @earmark IS NULL
) AS e
    ON vp.EarmarkId LIKE e.Value
但坦率地说,我会做一个条件逻辑:

IF @earmark IS NULL
    Select *
    from view_Project as vp
ELSE
    Select *
    from view_Project as vp
    INNER join inline_split_me(@earmark) as e on (vp.EarmarkId LIKE e.Value and @earmark IS NOT NULL)
如果你能摆脱这样的困境:

Select *
from view_Project as vp
WHERE @earmark IS NULL OR vp.EarmarkId IN (
    SELECT Value FROM inline_split_me(@earmark)
)

内部连接是你的问题。左连接将始终返回左侧的行,即使@earmark为NULL,连接条件也永远不会为true

Select *
from view_Project as vp
LEFT join inline_split_me(@earmark) as e on (vp.EarmarkId LIKE e.Value and @earmark IS NOT NULL)
当@earmark为NULL时,您可以使用联合来制造要连接的行

Select *
from view_Project as vp
INNER join (
    SELECT Value, -- columns here ...
    FROM inline_split_me(@earmark) as e
    UNION ALL
    SELECT DISTINCT vp.EarmarkId AS Value, -- NULL, NULL, etc.
    FROM view_Project
    WHERE @earmark IS NULL
) AS e
    ON vp.EarmarkId LIKE e.Value
但坦率地说,我会做一个条件逻辑:

IF @earmark IS NULL
    Select *
    from view_Project as vp
ELSE
    Select *
    from view_Project as vp
    INNER join inline_split_me(@earmark) as e on (vp.EarmarkId LIKE e.Value and @earmark IS NOT NULL)
如果你能摆脱这样的困境:

Select *
from view_Project as vp
WHERE @earmark IS NULL OR vp.EarmarkId IN (
    SELECT Value FROM inline_split_me(@earmark)
)

…作为vp加入\u拆分\u我(@earmark)作为…
应该默认为内部联接,这意味着只有在两个表之间找到匹配项时,查询才会返回行。(通过明确说出
内部联接
进行双重检查)


如果@earmark为null,函数调用是否返回no(零)行?如果是这样,那么应该没有从查询返回任何行。

…作为vp join lined\u split\u me(@earmark)作为…
应该默认为内部联接,这意味着只有在两个表之间找到匹配项时,查询才会返回行。(通过明确说出
内部联接
进行双重检查)


如果@earmark为null,函数调用是否返回no(零)行?如果是这样的话,那么查询应该不会返回任何行。

我知道这个问题已经很老了,但我在研究一个类似的问题时遇到了这个问题,并提出了一个完全不同的解决方案,效果非常好

使用左连接,但在WHERE子句中有一个过滤器,如果参数不为null,则连接匹配项也不能为null。这在功能上会导致条件内部联接

SELECT *
FROM 
  A 
  LEFT JOIN B 
    ON A.KEY = B.KEY
WHERE 
  (@JOIN_B IS NOT NULL AND B.KEY IS NOT NULL)
  OR @JOIN_B IS NULL

我知道这个问题已经很老了,但我在研究一个类似的问题时遇到了这个问题,并提出了一个完全不同的解决方案,效果非常好

使用左连接,但在WHERE子句中有一个过滤器,如果参数不为null,则连接匹配项也不能为null。这在功能上会导致条件内部联接

SELECT *
FROM 
  A 
  LEFT JOIN B 
    ON A.KEY = B.KEY
WHERE 
  (@JOIN_B IS NOT NULL AND B.KEY IS NOT NULL)
  OR @JOIN_B IS NULL

需要明确的是,如果@earmark为null,那么结果应该是view\u Project中的所有内容?如果是这样,您应该能够只执行左外联接,除非传递给inline\u split\u me的null值生成不需要的结果。是的,如果@earmark为null,则我希望查看\u Project的所有结果都是清晰的,如果@earmark为null,则结果应该是查看\u Project的所有结果?如果是这样的话,你应该可以只做一个左外连接,除非传递给inline_split_me的null值会产生不需要的结果。是的,如果@earmark为null,那么我希望所有结果都来自view_Project…刚才看到了第二条注释。是的,左外连接是你想要的…刚刚看到第二条评论。是的,左外连接是你想要的。嗯,我已经试过了,但是结果是每一行,不管我传递给sproc@MichaelFullom当
@earmark
不为空时,是否需要内部联接?在这种情况下,我会联合起来做伪指定标记-我会更新我的答案。是的,如果@earmark为null,我根本不需要进行连接,我只是想有一种方法可以根据param值是否为null来进行连接,但听起来我在这两种情况下都需要显式连接?@MichaelFullom是的,实际上,您正在从右连接更改为左连接,因为您的车辆是从存在专用标记时行驶的。我将在末尾发布另一个选项您的第四个选项使用嵌套的select使我更接近,它适用于null和值字符串,但不适用于“%”。在这种情况下,是否可以传递一个通配符,该通配符将为我提供所有专用标记,但不提供null?多谢各位!嗯,我已经试过了,但是结果是每一行,不管我传递给sproc@MichaelFullom当
@earmark
不为空时,是否需要内部联接?在这种情况下,我会联合起来做伪指定标记-我会更新我的答案。是的,如果@earmark为null,我根本不需要进行连接,我只是想有一种方法可以根据param值是否为null来进行连接,但听起来我在这两种情况下都需要显式连接?@MichaelFullom是的,实际上,您正在从右连接更改为左连接,因为您的车辆是从存在专用标记时行驶的。我将在末尾发布另一个选项您的第四个选项使用嵌套的select使我更接近,它适用于null和值字符串,但不适用于“%”。在这种情况下,是否可以传递一个通配符,该通配符将为我提供所有专用标记,但不提供null?多谢各位!