简化同一公式的多次出现

Posted

技术标签:

【中文标题】简化同一公式的多次出现【英文标题】:Simplify multiple occurrences of the same formula 【发布时间】:2018-03-06 13:15:27 【问题描述】:

是否可以简化多次编写相同公式的SEDE 查询?

例如,this query 写了五次rtrim(LOWER(Title))

select
    rtrim(LOWER(p.Title)),
    count(rtrim(LOWER(p.Title)))
from Posts p
group by rtrim(LOWER(p.Title))
having (count(rtrim(LOWER(p.Title))) > 1)
order by count(rtrim(LOWER(p.Title))) desc

在答案中,请说明您的因式分解是否纯粹是装饰性的,或者它是否也会对性能产生影响。

【问题讨论】:

对于COUNT()HAVINGORDER BY,您不需要RTRIM(LOWER( 位。您可以直接引用该列:p.Title @Siyual 我不明白为什么,但是是的,你似乎是对的:data.stackexchange.com/***/query/727327/siyual 【参考方案1】:

根据您查询的link,您似乎使用LOWER()RTRIM() 函数进行比较。

TSQL 默认情况下不区分大小写,并且忽略右侧的尾随空格。您可以通过以下方式获得相同的结果:

Select      Lower(P.Title), Count(P.Title)
From        Posts   P
Group By    Lower(P.Title)
Having      Count(P.Title) > 1
Order By    Count(P.Title) Desc

【讨论】:

@Cœur 有趣 - 我明白了。看起来确实需要 LOWER() - 我会调整我的答案。【参考方案2】:

首先 - 这里的永久解决方案是清理您的数据。使用 LTRIM、RTRIM、UPPER、LOWER 等函数会使您的SARGEable。换句话说,您的查询可能会慢到爬行,因为 SQL Server 不可能在不扫描所有行的情况下从索引中检索您需要的数据。

例如,这个查询写了五次 rtrim(LOWER(Title)):

输入 APPLY + VALUES 内联别名技巧

这是我前段时间为了简化我的代码而提出的,但后来我发现了一些偶尔的性能优势,我将对其进行演示。首先是一些示例数据:

use tempdb;
go

create table dbo.sometable(someid int identity, somevalue decimal(10,2));
insert dbo.sometable(somevalue) values (100),(1050),(5006),(111),(4);

假设我们有一个查询,它接受一些变量或参数,对它们执行计算并在整个查询中使用该值。请注意下面的案例陈述。

declare @var1 int = 100, @var2 int = 50, @var3 int = 900;

select
  someid, 
    somevalue,
    someCalculation = 
      case when @var3 < somevalue then (@var1 / (@var2*2.00))+@var3 else @var3+somevalue end,
  someRank = dense_rank() over (order by 
      case when @var3 < somevalue then (@var1 / (@var2*2.00))+@var3 else @var3+somevalue end)
from dbo.sometable
where case when @var3 < somevalue then (@var1 / (@var2*2.00))+@var3 else @var3+somevalue end
  between 900 and 2000
order by case when @var3 < somevalue then (@var1 / (@var2*2.00))+@var3 else @var3+somevalue end;

我们可以像这样简化这个查询:

select 
  someid, 
  somevalue,
  someCalculation = i.v,
  someRank = dense_rank() over (order by i.v)
from dbo.sometable
cross apply (values
(
  case when @var3 < somevalue then (@var1/(@var2*2.00))+@var3 else @var3+somevalue end)
) i(v)
where i.v between 900 and 2000
order by i.v;

每个查询都返回相同的结果。现在执行计划:

我们不仅简化了查询,实际上还加快了查询速度。在我的原始查询中,优化器必须计算两次相同的值并执行两种排序。使用我的内联别名技巧,我能够删除排序和计算

【讨论】:

以上是关于简化同一公式的多次出现的主要内容,如果未能解决你的问题,请参考以下文章

数字电路与系统-逻辑运算与简化(常用三个公式)

2 次或多次 OR 运算符的简化版本是啥? [关闭]

如何使用 rust 宏简化数学公式?

JavaScript新手问题 多次调用列表和简化判断多个值互不相等

应用程序脚本缓慢调用多次调用具有多个范围的相同函数,它调用 getValues

使用json数据动态创建表格2(多次绘制第一次简化 var tr=tbody.insertRow();)