2017-03-16 94 views
2

我有这种查询。但我需要优化此查询,以便如何省略具有相同拆分功能的冗余条件。如何删除** IN **查询中的冗余条件sql

DECLARE @Filter nvarchar(20) 
SELECT @Filter ='5,22,3' 

SELECT * FROM Employee e 
      WHERE e.code IN 
      (
      CASE WHEN((SELECT count(*) FROM dbo.FNSPLITSTRING(SUBSTRING(@Filter,1,LEN(@Filter)-1), ',') d 
            WHERE d.splitdata IN (5, 16, 20, 23, 33, 49, 62, 90, 91, 92, 93, 94))>0) THEN 5 ELSE 0 END 
      ,CASE WHEN((SELECT count(*) FROM dbo.FNSPLITSTRING(SUBSTRING(@Filter,1,LEN(@Filter)-1), ',') d 
            WHERE d.splitdata IN (22, 18))>0) THEN 46 ELSE 0 END 
      ,CASE WHEN((SELECT count(*) FROM dbo.FNSPLITSTRING(SUBSTRING(@Filter,1,LEN(@Filter)-1), ',') d 
            WHERE d.splitdata IN (3, 28))>0) THEN 3 ELSE 0 END 
      ) 
+3

最佳优化是停止使用包含逗号的字符串作为用于多个数据值的某种容器--SQL Server具有*设计*的数据类型以保存多个值 - 表和xml。 –

回答

0

我已经做了新的方法。较简单并省略冗余代码。

DECLARE @Filter nvarchar(20) 
SELECT @Filter ='5,22,3' 

SELECT Distinct e.EmployeeId FROM Employee e 
CROSS JOIN dbo.fnSplitString(@Filter, ',') AS d 
WHERE 
(e.code = 5 AND d.splitdata IN ('5', '16', '20', '23', '33', '49', '62', '90', '91', '92', '93', '94')) 
OR (e.code = 46 AND d.splitdata IN ('22', '18')) 
OR (e.code = 3 AND d.splitdata IN ('3', '28')) 
2

作为@Damien_The_Unbeliever说,避免拆分字符串作为值表。您不需要多次拆分相同的字符串。相反,您可以使用临时表变量。

DECLARE @SplitStrings TABLE 
(
    splitdata int 
) 

INSERT @SplitStrings 
SELECT splitdata FROM dbo.FNSPLITSTRING(SUBSTRING(@Filter,1,LEN(@Filter)-1), ',') d 

DECLARE @EmployeeCodes TABLE 
(
    splitdata INT, 
    code int 
) 

INSERT @EmployeeCodes (splitdata, code) 
VALUES (5, 5), (16, 5), (20, 5), (23, 5), (33, 5), (49, 5), (62, 5), (90, 5), (91, 5), (92, 5), (93, 5), (94, 5), 
     (22, 46), (18, 46), 
     (3, 3), (28, 3) 


SELECT e.* 
FROM Employee e 
JOIN @EmployeeCodes ec 
ON e.code = ec.code 
JOIN @SplitStrings ss 
ON ec.splitdata = ss.splitdata 

我希望这是您正在寻找的方向。

注意:假设您不需要0作为员工代码。

+1

这不是他所说的...... –

+0

@ZoharPeled是的,你是对的。实际上'@ Filter'是其他的代码。而在此基础上,我需要特定的员工。像EmployeeCode 46,3等 – SAL

+0

@SAL,请参阅更新,可能会对您有所帮助。 – Venu