SQL Server:CASE 语句中的 OR 语句



我有一个存储过程,它根据用户发送的内容查询一些员工记录。

在 UI 上,用户将输入多个数据点,例如电子邮件地址、用户 ID 或员工姓名。此存储过程检查它们提供的数据类型,然后在数据库中的该字段中搜索记录。

存储过程的输入:

<?xml version="1.0" encoding="UTF-8"?>
<root>
<data>
<dataPoints>
<dataPoint>
<order>0</order>
<value>Jim Bob</value>
</dataPoint>
<dataPoint>
<order>1</order>
<value>Sally Jones</value>
</dataPoint>
</dataPoints>
</data>
</root>

查询:

@dataType VARCHAR (20), @data XML
AS
BEGIN
SET NOCOUNT ON;
BEGIN
-- Create a temp table 
DECLARE @dataSet TABLE (data VARCHAR(100), [order] INT);
INSERT INTO @dataSet( data , [order] )
SELECT  
ParamValues.x1.value('value[1]', 'VARCHAR(100)') ,
ParamValues.x1.value('order[1]', 'INT') 
FROM 
@data.nodes('/root/data/dataPoints/dataPoint') AS ParamValues(x1)
-- Search Employees
SELECT 
ec.FirstName, ec.PreferredName, ec.LastName,
ec.NTID, ec.QID,
ec.DepartmentName, ec.SegmentName,
ec.CenterName, ec.RoleName, ec.MarketName,
ec.IncentivePlanName,
ec.CostCenterID,
ec.SupFirstName, ec.SupPreferredName, ec.SupLastName,
ec.SiloName,
ec.AreaName,
ec.PersonnelID,
d.[order]
FROM
Resources.emp.EmployeeComplete AS ec
INNER JOIN
@dataset AS d ON d.data = CASE 
WHEN @dataType = 'NTID' THEN ec.ntid 
WHEN @dataType = 'QID' THEN ec.QID 
WHEN @dataType = 'Emp ID' THEN ec.EmpID 
WHEN @dataType = 'Email Address' THEN ec.Email 
WHEN @dataType = 'Personnel ID' OR @dataType = 'Sap ID' THEN ec.PersonnelID 
--WHEN @dataType = 'Name' THEN (
-- (ec.FirstName + ' ' + ec.LastName) 
--     OR (ec.PreferredName + ' ' + ec.LastName)
--     OR (ec.LastName + ', ' + ec.FirstName)
--     OR (ec.LastName + ', ' + ec.PreferredName
-- )
END
FOR XML PATH ('employees'), ELEMENTS, TYPE, ROOT ('root');

简而言之,我获取要搜索的多个数据点,并将它们放入 XML 字符串中以传递给存储过程。一旦他们到达,我就把它们放到一个临时表中,这样我就可以把它与我的主要员工记录结合起来。

问题/问题:

您将看到我的示例中有一些注释掉的代码,这就是我的问题所在。我的数据库中有三个名称字段。First NamePreferred NameLast Name

我基本上需要测试用户提供的内容,并根据他们输入的组合找到员工。用户在 UI 中选择的所有内容都是他们提供的名称,而不是其格式。

出于这个原因,我需要检查是否可以找到几种不同格式的记录。

在这种情况下,问题是我无法使用CASE语句中的OR条件联接我的数据集。

如果@dataType = 'Name',我需要能够加入我的临时表,以几种不同的组合可能性。

我们让他们意识到的一件事是他们不能混合搭配。这意味着他们无法通过LastName FirstName搜索进行FirstName LastName

我很难解释这一点,所以如果我需要以某种方式澄清,请告诉我。

将方程推入CASE。如果为真,则让THEN返回 1。检查CASE是否返回 1。当且仅当它确实如此时,您才找到了匹配项。在WHEN条件下,您可以使用布尔运算符。因此,您可以在那里构建OR(或使用IN,如下所示(。

...
CASE 
WHEN @dataType = 'NTID' AND d.data = ec.ntid THEN 1
WHEN @dataType = 'QID' AND d.data = ec.QID THEN 1
...
WHEN (@dataType = 'Personnel ID' OR @dataType = 'Sap ID') AND d.data = ec.PersonnelID THEN 1
WHEN @dataType = 'Name' AND (d.data IN ('' + ec.FirstName + ' ' + ec.LastName, 
'' + ec.PreferredName + ' ' + ec.LastName,
'' + ec.LastName + ', ' + ec.FirstName,
'' + ec.LastName + ', ' + ec.PreferredName) THEN 1
END = 1
...

把 OR 放在你的连接中怎么样?

FROM    @dataset AS d
INNER JOIN Resources.emp.EmployeeComplete AS ec
ON (@dataType = 'NTID' AND ec.ntid = d.data)
OR (@dataType = 'QID' AND ec.QID = d.data)
OR (@dataType = 'Emp ID' AND ec.EmpID = d.data)
OR (@dataType = 'Email Address' AND ec.Email = d.data)
OR ((@dataType = 'Personnel ID' OR @dataType = 'Sap ID') AND ec.PersonnelID = d.data)
OR (@dataType = 'Name' AND (ec.FirstName + ' ' + ec.LastName) = d.data)
OR (@dataType = 'Name' AND (ec.PreferredName + ' ' + ec.LastName) = d.data)
OR (@dataType = 'Name' AND (ec.LastName + ', ' + ec.FirstName) = d.data)
OR (@dataType = 'Name' AND (ec.LastName + ', ' + ec.PreferredName) = d.data)

我不确定 SQL 是否足够聪明,可以在这些字段上使用正确的索引(如果有的话(,尤其是在组合列时可能不是。 您将为这些组合名称创建索引视图,或为可编制索引的计算列。 最好将它们分散到 if/thens 中的单独查询中,以便 SQL 可以根据您加入的字段优化每个查询,并只执行一个查询。

最新更新