SQL查找GROUP BY中MIN的值

时间:2015-04-02 03:34:46

标签: sql sql-server group-by aggregate-functions

我正在创建表的摘要视图。我想检索一个字段是MAX / MIN的日期,所有分组(这是一个摘要)。我现在正在使用它,它可以工作,但它在许多领域都非常缓慢:

SELECT A.Timestamp, A.Date

-- FIND MAX VALUE
MAX(A.Field1) AS MaxDate,

-- FIND DATE AT MAX-VALUE
(SELECT Date
FROM MyTable
WHERE Field1 = MAX(A.Field1)
AND Timestamp = A.Timestamp
AND Date = A.Date)

-- DO THE SAME FOR MIN VALUE, MEDIAN VALUE, ETC, ETC

FROM MyTable AS A
GROUP BY A.Timestamp, A.Date

我在很多领域做过类似的操作。任何人都可以建议一个更好的方法吗?感谢

2 个答案:

答案 0 :(得分:0)

我认为索引可能会解决您的性能问题:

create index idx_mytable_date_timestamp_field1 on mytable(date, timestamp, field1);

答案 1 :(得分:0)

戈登提到的索引应该涵盖您的查询并加快速度。你做这件事的方式没有什么特别的错误;但是,我想尝试在一个查询中获取聚合。

我对你的架构做了一些假设,如果我误入歧途,请告诉我。在这里,我使用索引器对asc&中的所有值进行排序。 desc order,然后使用这两个索引来查找最小值,最大值和媒体值/日期。

注意:请确保根据需要处理关系

if object_id('tempdb..#t') is not null 
    drop table #t;

create table #t ([pk] int, [Date] date, [Timestamp] time, Field1 decimal primary key(pk, [date]));
insert into #t
    values  (1, '01-01-2001', '13:00', 10),
            (1, '01-02-2001', '13:00', 20),
            (1, '01-03-2001', '13:00', 30),
            (1, '01-04-2001', '13:00', 40),
            (1, '01-05-2001', '13:00', 50),
            (1, '01-06-2001', '13:00', 50),
            --
            (2, '02-01-2001', '13:00', 10),
            (2, '02-02-2001', '13:00', 90),
            (2, '02-03-2001', '13:00', 70),
            (2, '02-04-2001', '13:00', 0),
            (2, '02-05-2001', '13:00', 33)



select  pk,
        [median] = min(case when Up in (Down, Down - 1, Down + 1) then Field1 else null end),
        [medianDate] = min(case when Up in (Down, Down - 1, Down + 1) then [Date] else null end),
        [minValue] = min(case when Up = 1 then Field1 else null end),
        [minDate] = min(case when Up = 1 then [Date] else null end),
        [maxValue] = min(case when Down = 1 then Field1 else null end),
        [maxDate] = min(case when Down = 1 then [Date] else null end)
from    (   select  pk,
                    Field1,
                    [Date],
                    row_number() over (partition by pk order by Field1 asc),
                    row_number() over (partition by pk order by Field1 desc) 
            from    #t
        ) d (pk, Field1, [Date], Up, Down)
group
by      pk;

返回:

pk  median  medianDate  minValue    minDate     maxValue    maxDate
1   30      2001-01-03  10          2001-01-01  50          2001-01-05
2   33      2001-02-05  0           2001-02-04  90          2001-02-02