【问题标题】:SQL Server 2012: distinct with over clause in an aggregate functionSQL Server 2012:在聚合函数中与 over 子句不同
【发布时间】:2016-01-29 15:19:40
【问题描述】:

使用 over (partition by) 编写聚合函数的正确语法是什么?

或者这怎么可能被重写?我没有一些示例表,因为我将其作为自己的练习。我想知道这是否可能。请在下面找到我正在考虑的场景。​​

我们以一个简单的例子为例:

select 
    *,
    sum (column1 * column2) over (partition by column10, colum12)/100 as sumProduct
into #myTemp
from myTable

上面的查询适用于具有这些列的表。 现在,我怎样才能为column1column2 的不同值编写相同的内容?

下面的查询不起作用,但它是我想要实现的伪。

预期的结果非常简单(参见distinct column1 * distinct column2

select 
    *,
    sum (distinct column1 * distinct column2) over (partition by column10, colum12)/100 as sumProduct
into #myTemp
from myTable

编辑:我想避免group by。我正在尝试尽可能多地使用分区,以便在窗口功能方面做得更好

【问题讨论】:

  • 你不能在windows功能中与众不同。首先在 cte 中做一个 distinct 然后应用你的函数。
  • 聚合或窗口函数——除了COUNT()——不应使用DISTINCT

标签: sql sql-server tsql sql-server-2012 window-functions


【解决方案1】:

distinctcount() 以外的聚合一起使用通常是不正确的。对于窗口函数和聚合函数都是如此。

您可以使用row_number() 和条件聚合来完成count(distinct) 的等效操作:

select t.*,
       sum(case when seqnum = 1 then 1 else 0 end) as CountDistinct
into #myTemp
from (select t.*,
             row_number() over (partition by column10, colum12 order by (select NULL)) as seqnum
      from myTable t
     ) t;

编辑:

COUNT(DISTINCT) 不同,以上将NULL 值计为“有效”值。这很容易解决:

select t.*,
       count(case when seqnum = 1 then colum12 end) as CountDistinct
into #myTemp
from (select t.*,
             row_number() over (partition by column10, colum12 order by (select NULL)) as seqnum
      from myTable t
     ) t;

【讨论】:

  • 如果来自columncolumn2 的值是/将是NULL,这是否也有效?很好的答案
  • @CM2K 。 . .这对NULL 的处理略有不同,因为它将其视为有效值。我添加了一个一致的版本,即使对于 NULL 值也是如此。
  • 我是CTErow_number() 的初学者(老实说,只是简单地阅读了关于它们从未使用过它们的信息)。我理解这里的逻辑(或者,至少我希望如此),但是如何计算/合并sumProduct,如问题所示到您的查询中?
  • @CM2K 。 . .我不建议这样做。
  • count()以外的聚合函数与distinct一起使用通常表明数据结构有问题,我觉得这很危险(当然,min()或@987654340没有必要这样做@)。规范化您的数据或在子查询中使用select distinct
猜你喜欢
  • 2021-06-29
  • 1970-01-01
  • 2012-12-19
  • 1970-01-01
  • 2012-12-07
  • 2015-12-29
  • 2013-08-14
  • 1970-01-01
  • 2013-02-10
相关资源
最近更新 更多