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

时间:2012-02-06 19:43:50

标签: 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'或'119,120,121'的字符串,这个连接应该发生并产生正确的结果。如果@earmark为null,我想它根本不会发生,我认为我可以使用和@earmark不是null来描述它然而它没有返回正确的结果,这是通过注释连接发现的在@earmark param中输出并运行与null相同的sproc,这样就可以得到所有行。当我保持这个连接并传递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)

得到它,谢谢Cade Roux和其他人

if (@earmark = '%')
select *
    from view_Project as vp
    where vp.EarmarkId like @earmark
else
select *
    from view_Project as vp
    where @earmark is null or vp.EarmarkId in (select Value from inline_split_me(@earmark))

3 个答案:

答案 0 :(得分:4)

INNER JOIN是你的问题。 LEFT JOIN将始终返回LEFT上的行,即使@earmark为NULL时,连接条件也永远不会为真。

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

时,您可以使用UNION来制造要加入的行
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)

如果你能离开LIKE:

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

答案 1 :(得分:0)

...as vp join lined_split_me(@earmark) as... 应默认为内部连接,这意味着只有在两个表之间找到匹配项时,查询才会返回行。 (通过明确说出inner join来仔细检查。)

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

答案 2 :(得分:0)

我知道这个问题已经很老了,但我正在研究一个类似的问题并遇到了这个问题,并想出了一个完全不同的解决方案,就像一个魅力。

使用 LEFT JOIN,但在 WHERE 子句中有一个过滤器,如果您的参数不为空,则您的连接匹配也不能为空。这在功能上会导致有条件的 INNER JOIN。

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