【问题标题】:How to remove redundant conditions in **IN** query Sql如何去除**IN**查询Sql中的冗余条件
【发布时间】:2017-08-07 06:40:09
【问题描述】:

我有这样的疑问。但是我需要优化这个查询,所以如何省略具有相同拆分功能的冗余条件。

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
             )

【问题讨论】:

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

标签: sql-server tsql optimization query-optimization


【解决方案1】:

正如@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 作为员工代码。

【讨论】:

  • @ZoharPeled 是的,你说得对。实际上@Filter 是另一个代码。在此基础上,我需要特定的员工。比如 EmployeeCode 46,3 等
【解决方案2】:

我做了新的方法。不太复杂并省略了冗余代码。

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'))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    • 1970-01-01
    • 2020-09-29
    • 2014-10-05
    相关资源
    最近更新 更多