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.Name
是 ID
并且转换模式匹配,则行匹配,或者如果 b.Name
是 DisplayName
并且显示名称类似于 b.Value
,行匹配。
试一试。
我必须指出,在给定多行的情况下,这可能无法很好地缩放。您真的应该对每种情况都有一个单独的查询,以便 SQL 服务器可以使用适当的索引和统计信息。
在您的代码中:
WHEN 'Id' THEN CONVERT(varchar(10), a.Id) = b.Value
WHEN 'DisplayName' THEN a.DisplayName like b.Value END
= b.Value
和 like 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
我正在尝试实现一种方法来替换 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.Name
是 ID
并且转换模式匹配,则行匹配,或者如果 b.Name
是 DisplayName
并且显示名称类似于 b.Value
,行匹配。
试一试。
我必须指出,在给定多行的情况下,这可能无法很好地缩放。您真的应该对每种情况都有一个单独的查询,以便 SQL 服务器可以使用适当的索引和统计信息。
在您的代码中:
WHEN 'Id' THEN CONVERT(varchar(10), a.Id) = b.Value
WHEN 'DisplayName' THEN a.DisplayName like b.Value END
= b.Value
和 like 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