over partition by没有聚合函数,避免group by

时间:2015-10-27 15:15:11

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

有没有什么方法可以使用over (partition by column)等窗口函数而不将其用作聚合函数?

我有很多专栏和我不想使用分组,因为我必须在select和group by中指定。

我给出了一个语法示例,需要以某种方式进行纠正(由于你们在我的真实查询中调整它时它会导致它不起作用(实际查询太长而且耗时很难解释它)举个例子))。

让我们假设这是有效的:

select *,
( select
sum (column1) over (partition by column2) as sumCol1
from myTable
where column20 = column21
)
from myTable
好的,现在我想做两件事做同样的事情:

1:没有汇总功能

2: column1这次是DATE(我目前无法使用date的聚合函数据我所知,但正如我试图消除聚合,这不重要。)

我想要的应该是这样的(查询不正确,因为这是我试图实现的目标)

  select *,
    ( select
    column1 over (partition by column2) as Col1New
    from myTable
    where column20 = column21
    )
    from myTable

SQL Server 2012

由于

编辑:

示例数据:

     rN         rD          rnc      d     e   name  
    abc1m      2010-03-31   abc     5.7    2   blue   
    abc3m      2010-04-15   abc     5.7    3   blue  
    abc1y      2010-02-14   abc     5.7    4   blue   
    xfx1m      2010-02-31   xfx     1.7    2   blue  
    xfx3m      2010-03-24   xfx     1.7    1   blue  
    xfx1y      2012-03-30   xfx     1.7    1.7 red    <= d=e use this date for "red" rows
    tnt1m      2010-03-28   tnt     9.6    2   red   
    tnt3m      2010-01-12   tnt     9.6    9.6 blue   <= d=e use this date for "blue" rows
    tnt1y      2010-08-20   tnt     9.6    2   red 

预期表格,请查看expectedCol

rN         rD          rnc      d     e   name  expectedCol
abc1m      2010-03-31   abc     5.7    2   blue  2010-01-12 
abc3m      2010-04-15   abc     5.7    3   blue  2010-01-12 
abc1y      2010-02-14   abc     5.7    4   blue  2010-01-12 
xfx1m      2010-02-31   xfx     1.7    2   blue  2010-01-12 
xfx3m      2010-03-24   xfx     1.7    1   blue  2010-01-12 
xfx1y      2012-03-30   xfx     1.7    1.7 red   2012-03-30 
tnt1m      2010-03-28   tnt     9.6    2   red   2012-03-30 
tnt3m      2010-01-12   tnt     9.6    9.6 blue  2010-01-12 
tnt1y      2010-08-20   tnt     9.6    2   red   2012-03-30 

逻辑是这样的:当d = e然后查看rD并获取该日期并按名称将其放入expectedCol1组

所以,我想写这样的东西:

select *,
(select rD over (partition by name) as expectedCol1
from myTable
where d = e)
from myTable

3 个答案:

答案 0 :(得分:1)

只需为rD

中的每个name计算d = e
WITH myDate AS ( 
      SELECT name, rD
      FROM YourTable
      WHERE d = e
)
SELECT
       t.*, m.rD as expectedCol           
FROM YourTable t
JOIN myDate m
  ON t.name = m.name

答案 1 :(得分:1)

从您的示例数据中,类似这样的内容看起来应该可行:

select t1.*,t2.rD as expectedCol1
from myTable t1
inner join (select name,rD from myTable where e = d) t2
on t1.name = t2.name

由于您已声明e = d组合仅针对每个名称出现一次,因此t2子查询应为每个名称包含一行。如果某些名称可能没有e = d的行,如果您希望包含这些行,则应更改为left join,然后考虑expectedCol1在这种情况下应该是什么。

答案 2 :(得分:1)

正如我在评论中提到的,执行此操作的第三种方法是使用简单的子查询:

SELECT t.*, (
  SELECT rD FROM myTable t2 WHERE t2.e=t2.d AND t2.Name=t.Name
) AS ExpectedCol
FROM myTable t