LEFT JOIN 与 CASE WHEN

LEFT JOIN with CASE WHEN

我正在尝试实现一种方法来替换 WHERE 子句的 "dynamic SQL"。
也就是创建一个temp table, "#FilterTable",里面包含了我的WHERE的名字和值。
然后,我使用 "left join" 映射我的目标 table #Hotel 和 #FilterTable。
但是,使用以下代码时出现错误:

DECLARE @filterName varchar(50)='Id',
    @filterValue int =13

CREATE TABLE #Hotel (Id varchar(50), DisplayName varchar(100))
CREATE TABLE #FilterTable (Name varchar(50), Value varchar(100))
INSERT INTO #Hotel(Id,DisplayName) VALUES ('1','California Inn'), ('13','Hilton Hotel')
INSERT INTO #FilterTable(Name,Value) VALUES ('Id','13'),('DisplayName','Hotel')

SELECT a.* 
FROM #Hotel a WITH(NOLOCK)
LEFT JOIN #FilterTable b WITH(NOLOCK) 
ON @filterName= b.Name
AND 
   CASE b.Name  
   WHEN 'Id' THEN  CONVERT(varchar(10), a.Id) = b.Value
   WHEN 'DisplayName' THEN a.DisplayName like b.Value END

DROP Table #Hotel
DROP Table #FilterTable


中总是显示错误
WHEN 'Id' THEN  CONVERT(varchar(10), a.Id) = b.Value
WHEN 'DisplayName' THEN a.DisplayName like b.Value END

换成

就知道了
WHEN 'DisplayName' THEN CONVERT(varchar(10), a.Id) END = b.Value

,会通过,但是这种情况下没办法在"WHEN"子句中加入第二个条件。

有谁知道将这两个 "WHEN" 子句放在一起的正确语法是什么?
我的数据库版本是 SQL SERVER 2014 Enterprise。
谢谢。

您的 CASE 语法不正确。您像使用 C 中的 switch 语句、Java 等一样使用它。您不会针对某个值说大小写,然后打开该值。相反,它就像一个 if 语句,其中每个条件都是独立的。

SELECT a.*
FROM #Hotel a WITH(NOLOCK)
LEFT JOIN #FilterTable b WITH(NOLOCK)
ON @filterName= b.Name
AND
   CASE
     WHEN b.Name = 'Id' AND  CONVERT(varchar(10), a.Id) = b.Value THEN 1
     WHEN b.Name = 'DisplayName' AND a.DisplayName like b.Value THEN 1
     ELSE 0
   END = 1

这表示,如果 b.NameID 并且转换模式匹配,则行匹配,或者如果 b.NameDisplayName 并且显示名称类似于 b.Value,行匹配。

试一试。

我必须指出,在给定多行的情况下,这可能无法很好地缩放。您真的应该对每种情况都有一个单独的查询,以便 SQL 服务器可以使用适当的索引和统计信息。

在您的代码中:

WHEN 'Id' THEN  CONVERT(varchar(10), a.Id) = b.Value
WHEN 'DisplayName' THEN a.DisplayName like b.Value END

= b.Valuelike b.Value 等于 = b.Value。如果你想使用 LIKE 你必须添加:like '%' + b.Value + '%'

但如果这并不意味着你可以使用:

b.Value = CASE b.Name  
          WHEN 'Id' THEN  CONVERT(varchar(10), a.Id)
          WHEN 'DisplayName' THEN a.DisplayName END