我正在创建表的摘要视图。我想检索一个字段是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
我在很多领域做过类似的操作。任何人都可以建议一个更好的方法吗?感谢
答案 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