Имеется некая табличка, к которой обращаются с запросами. В запросах имееюся некая группировка и выборка значений. Например:
CREATE TABLE [#T] (
[Number] int,
[DateTime] datetime,
[Value] nchar,
);
INSERT [#T] ([Number], [DateTime], [Value]) VALUES (1, N'2010-01-01', N'D');
INSERT [#T] ([Number], [DateTime], [Value]) VALUES (1, N'2010-01-01', N'E');
INSERT [#T] ([Number], [DateTime], [Value]) VALUES (1, N'2010-01-02', N'A');
INSERT [#T] ([Number], [DateTime], [Value]) VALUES (1, N'2010-01-03', N'B');
INSERT [#T] ([Number], [DateTime], [Value]) VALUES (1, N'2010-01-03', N'C');
INSERT [#T] ([Number], [DateTime], [Value]) VALUES (1, N'2010-02-01', N'3');
INSERT [#T] ([Number], [DateTime], [Value]) VALUES (1, N'2010-02-01', N'2');
INSERT [#T] ([Number], [DateTime], [Value]) VALUES (1, N'2010-02-02', N'1');
INSERT [#T] ([Number], [DateTime], [Value]) VALUES (1, N'2010-02-03', N'4');
INSERT [#T] ([Number], [DateTime], [Value]) VALUES (1, N'2010-02-03', N'5');
INSERT [#T] ([Number], [DateTime], [Value]) VALUES (2, N'2010-01-01', N'U');
INSERT [#T] ([Number], [DateTime], [Value]) VALUES (2, N'2010-01-01', N'V');
INSERT [#T] ([Number], [DateTime], [Value]) VALUES (2, N'2010-01-02', N'X');
INSERT [#T] ([Number], [DateTime], [Value]) VALUES (2, N'2010-01-03', N'Z');
INSERT [#T] ([Number], [DateTime], [Value]) VALUES (2, N'2010-01-03', N'Y');
SELECT [Number], MONTH([DateTime]) [Month], MIN([Value]) [Value]
FROM [#T]
GROUP BY [Number], MONTH([DateTime]);
DROP TABLE [#T];
Результат:
Number Month Value
1 1 A
2 1 U
1 2 1
Требуется уметь считать по [Value] не только стандартные COUNT/AVG/SUM/MIN/MAX но, например, и FIRST и LAST — то есть в пределах группы требуется найти строку с минимальным или максимальным значением [DateTime] и вернуть значение [Value] этой строки.
У меня вышло как-то сложновато:
SELECT T.[Number], T.[Month], X.[Value]
FROM (SELECT [Number], MONTH([DateTime]) [Month], MIN([DateTime]) [Order] FROM [#T] GROUP BY [Number], MONTH([DateTime])) T
JOIN (SELECT [Number], [DateTime] [Order], MIN([Value]) [Value] FROM [#T] GROUP BY [Number], [DateTime]) X
ON X.[Number] = T.[Number] AND T.[Order] = X.[Order];
Number Month Value
1 1 D
1 2 2
2 1 U
В реальности количество строк в таблице — несколько миллионов. Агрегаты над [DateTime] не просто MONTH() а немного более хитрые вычисления (Начало/конец года, например). Смущает необходимость дважды считать группы.
Может ли кто подсказать, как можно упростить второй запрос или, вообще, решить задачу другим, более правильным способом?