sql server—有没有更好的方法来编写此sql?

puruo6ea  于 2021-07-24  发布在  Java
关注(0)|答案(2)|浏览(312)

所以我为一个报表创建了一个查询,这个报表可以有几个可选的过滤器。为了简单起见,我只在这里加入了客户和电台。每个选项都可以是include或exclude,并且可以包含null、1或多个值。因此,在将varchar连接到查询之前,我将其拆分为一个表。
这个测试大约需要15分钟来执行,这。。。就是不行:p有更好的办法吗?我们用动态sql编写了类似的查询,我试图避免这种情况,但可能没有办法解决这个问题?

DECLARE   
@ClientsInc VARCHAR(10) = 'ABCD, EFGH', 
@ClientsExc VARCHAR(10) = NULL,     
@StationsInc VARCHAR(10) = NULL, 
@StationsExc VARCHAR(10) = 'SomeStation'

SELECT *
INTO #ClientsInc
FROM dbo.StringSplit(@ClientsInc, ',')
SELECT *
INTO #ClientsExc
FROM dbo.StringSplit(@ClientsExc, ',')

SELECT *
INTO #StationsInc
FROM dbo.StringSplit(@StationsInc, ',')
SELECT *
INTO #StationsExc
FROM dbo.StringSplit(@StationsExc, ',')    

SELECT [some stuff]
FROM media_order mo
LEFT JOIN #ClientsInc cInc WITH(NOLOCK) ON cInc.Value = mo.client_code
LEFT JOIN #ClientsExc cExc WITH(NOLOCK) ON cExc.Value = mo.client_code
LEFT JOIN #StationsInc sInc WITH(NOLOCK) ON sInc.Value = mo.station_name
LEFT JOIN #StationsExc sExc WITH(NOLOCK) ON sExc.Value = mo.station_name
WHERE ((@ClientsInc IS NOT NULL AND cInc.Value IS NOT NULL)
         OR (@ClientsExc IS NOT NULL AND cExc.Value IS NULL)
       )    
   AND ((@StationsInc IS NOT NULL AND sInc.Value IS NOT NULL)
         OR (@StationsExc IS NOT NULL AND sExc.Value IS NULL)
        )
yhxst69z

yhxst69z1#

首先,在这种情况下,我总是倾向于提到erlandsommarskog的动态搜索条件。
但是,您似乎已经意识到了两个选项:一个是动态sql。另一个通常是老把戏 and (@var is null or @var=respective_column) . 然而,这个技巧只适用于每个变量的一个值。
您的解决方案似乎确实适用于多个值。但在我看来,您试图避免使用动态sql太难了。你的要求很复杂,足以保证。请记住,通常情况下,动态sql对您来说更难编写代码,但对于复杂情况下的服务器来说更容易编写代码—这一点当然是。猜测性能总是有风险的,但我想在这种情况下会有所改进。

5w9g7ksd

5w9g7ksd2#

我会用 exists 以及 not exists :

select ...
from media_order mo
where
    (
        @ClientsInc is null
        or exists (
            select 1 
            from string_split(@ClientsInc, ',')
            where value = mo.client_code
        )
    )
    and not exist (
        select 1 
        from string_split(@ClientsExc, ',')
        where value = mo.client_code
    )
    and (
        @StationsInc is null
        or exists (
            select 1 
            from string_split(@StationsInc, ',')
            where value = mo.station_name
        )
    )
    and not exist (
        select 1 
        from string_split(@StationsExc, ',')
        where value = mo.station_name
    )

笔记:
我用了内置函数 string_split() 而不是您似乎正在使用的自定义拆分器。它在sql server 2016及更高版本中可用,并返回一个名为 value . 如果运行的是早期版本,则可以将其更改回客户功能
根据我的理解,在使用之前需要检查“include”参数是否为空 exists ,而“exclude”变量则不需要

相关问题