挑战SQL分组

时间:2009-11-05 18:12:31

标签: sql sql-server-2005

我有一个问题:

select  event_type, 
    department_name,
    effective_time,
    row_number() OVER (PARTITION BY event_type,department_name ORDER BY effective_time) row
from    a
order by effective_time

它返回一个行集:

event_type  department_name effective_time
3   A   02/10/09 13:12:00
3   B   02/10/09 15:44:00
3   B   02/10/09 20:36:00
7   C   04/01/09 00:01:00
7   D   04/10/09 00:01:00
7   D   04/20/09 00:01:00
7   E   04/20/09 00:01:00
7   F   04/23/09 09:32:00
7   F   05/15/09 12:21:00
7   G   05/15/09 12:21:00
7   H   05/15/09 12:21:00
1   H   07/28/09 08:51:00
1   G   07/28/09 08:51:00
1   F   07/28/09 10:40:00
1   F   07/28/09 12:34:00
1   H   07/28/09 12:34:00
1   G   07/28/09 12:34:00
1   D   07/29/09 10:45:00
1   D   07/29/09 12:48:00
1   G   07/31/09 13:47:00
1   F   07/31/09 13:47:00
1   D   08/03/09 00:01:00
3   B   08/03/09 10:39:00

我需要行集看起来像:

event_type  department_name effective_time
3   A   02/10/09 13:12:00
3   B   02/10/09 15:44:00
7   C   04/01/09 00:01:00
7   D   04/10/09 00:01:00
7   E   04/20/09 00:01:00
7   F   04/23/09 09:32:00
7   G   05/15/09 12:21:00
7   H   05/15/09 12:21:00
1   H   07/28/09 08:51:00
1   G   07/28/09 08:51:00
1   F   07/28/09 10:40:00
1   H   07/28/09 12:34:00
1   G   07/28/09 12:34:00
1   D   07/29/09 10:45:00
1   G   07/31/09 13:47:00
1   F   07/31/09 13:47:00
1   D   08/03/09 00:01:00
3   B   08/03/09 10:39:00

基本上,删除组中给定event_type和department_name的第二(或更多)次出现。

我希望通过消除所有行#>来使用row_number来解决这个问题。 1。

不幸的是,正如所写的那样,row_number()函数在event_type和department_name发生更改后无法重置行计数器。

问题:

  1. 可以调整row_number()计算吗?
  2. 是否有其他方法可以更有效地工作?
  3. 这可以在没有程序化干预的情况下完成(即存储过程或UDF)吗?
  4. 感谢您的协助。

4 个答案:

答案 0 :(得分:2)

试试这个:

SELECT event_type, 
    department_name,
    MIN(effective_time)
FROM    a
GROUP BY event_type, 
    department_name
ORDER BY effective_time

答案 1 :(得分:2)

对,在阅读你的评论后,我想我明白了。一种方法是基于effective_time对子查询中的行进行编号。使用这些数字可以轻松搜索上一行。然后,您可以通过说明每行必须与其前一行不同来过滤掉“重复”行。

以下是一个示例查询:

;with numbered as (
    SELECT event_type, department_name, effective_time,
           row_number() OVER (ORDER BY effective_time) row
    FROM a
)
SELECT    cur.event_type, cur.department_name, cur.effective_time
FROM      numbered cur
LEFT JOIN numbered prev ON cur.row = prev.row + 1
WHERE     cur.row = 1
          or prev.event_type <> cur.event_type
          or prev.department_name <> cur.department_name
ORDER BY  cur.effective_time

顺便说一句,如果您喜欢测试答案,请将示例数据发布为文本而不是jpg图像:)

答案 2 :(得分:0)

您可以按event_type,department_name执行分组。唯一的事情就是日期,你必须将它添加到像min(date)或group by这样的聚合中是没有意义的。

select  event_type, 
    department_name,
    convert(varchar, effective_time, 1) as date

from    a
group by event_type, department_name, convert(varchar, effective_time, 1)
order by effective_time

答案 3 :(得分:0)

select  event_type, 
    department_name,
    min(effective_time) as effTime,
from    a
group by event_type, department_name
order by effective_time

这有帮助吗?