Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 [help] написать запрос MAX()  [new]
ilyaBS
Member

Откуда: Киев
Сообщений: 77
Есть таблица с данными Source(log_date,name,value). Необходимо найти максимальное value за каждую дату и Name этому значению соответствующее.

входные данные:
log_date NAME VALUE
2014-03-01 aaa 100501.876
2014-03-02 aaa 100800.452
2014-03-03 aaa 100400.945
2014-03-01 bbb 104500.887
2014-03-02 bbb 100600.260
2014-03-03 bbb 100000.969
2014-03-01 ccc 100500.992
2014-03-02 ccc 100500.008
2014-03-03 ccc 100967.061
2014-03-04 aaa 0.000
2014-03-04 bbb 0.000
2014-03-04 ccc 0.000

Ожидаемый результат:
log_date MName MaxValueForDate
2014-03-01 bbb 104500.887
2014-03-02 aaa 100800.452
2014-03-03 ccc 100967.061
2014-03-04 aaa 0.000

Запрос я написал, но он мне не нравится тройным вложением запросов и Row_Number коммандой. Вот мой код:

IF OBJECT_ID('tempdb..#source') IS NOT NULL DROP TABLE #source
CREATE TABLE #source (log_date DATE, NAME VARCHAR(30), VALUE DECIMAL(10,3))
INSERT INTO #source
SELECT '1-mar-2014', 'aaa', 100501.876 UNION all
SELECT '2-mar-2014', 'aaa', 100800.452 UNION all
SELECT '3-mar-2014', 'aaa', 100400.945 UNION all
SELECT '1-mar-2014', 'bbb', 104500.887 UNION all
SELECT '2-mar-2014', 'bbb', 100600.26 UNION all
SELECT '3-mar-2014', 'bbb', 100000.969 UNION all
SELECT '1-mar-2014', 'ccc', 100500.992 UNION all
SELECT '2-mar-2014', 'ccc', 100500.008 UNION all
SELECT '3-mar-2014', 'ccc', 100967.061 UNION all
SELECT '4-mar-2014', 'aaa', 0 UNION all
SELECT '4-mar-2014', 'bbb', 0 UNION all
SELECT '4-mar-2014', 'ccc', 0 

SELECT * FROM #source

SELECT log_date,MName,MaxValueForDate FROM 
	(
	SELECT s.log_date,s.NAME MName, s.VALUE MaxValueForDate, ROW_NUMBER() OVER (PARTITION BY s.log_date ORDER BY s.VALUE DESC) rowid
	FROM #source s 
		INNER JOIN 
		(SELECT log_date,MAX(VALUE) MValue FROM #source GROUP BY log_date) res
	ON s.log_date = res.log_date AND s.VALUE = res.MValue
	) final
WHERE final.rowid = 1	


Можно ли его как-то написать иначе?
17 мар 14, 20:58    [15741460]     Ответить | Цитировать Сообщить модератору
 Re: [help] написать запрос MAX()  [new]
iap
Member

Откуда: Москва
Сообщений: 47052
SELECT TOP(1) WITH TIES *
FROM [Source]
ORDER BY RANK()OVER(PARTITION BY [log_date] ORDER BY [value] DESC);
???
17 мар 14, 21:02    [15741479]     Ответить | Цитировать Сообщить модератору
 Re: [help] написать запрос MAX()  [new]
iap
Member

Откуда: Москва
Сообщений: 47052
RANK() - это на случай, если равных максимальных значений несколько
17 мар 14, 21:02    [15741484]     Ответить | Цитировать Сообщить модератору
 Re: [help] написать запрос MAX()  [new]
ilyaBS
Member

Откуда: Киев
Сообщений: 77
iap,

дык дубликаты для 4го числа остаются
17 мар 14, 21:05    [15741504]     Ответить | Цитировать Сообщить модератору
 Re: [help] написать запрос MAX()  [new]
iap
Member

Откуда: Москва
Сообщений: 47052
ilyaBS
iap,

дык дубликаты для 4го числа остаются
Что оставлять, если Name будут разные?

Ну, замените RANK() на ROW_NUMBER()
17 мар 14, 21:07    [15741517]     Ответить | Цитировать Сообщить модератору
 Re: [help] написать запрос MAX()  [new]
ilyaBS
Member

Откуда: Киев
Сообщений: 77
iap,

супер. спасибо большое.
17 мар 14, 21:09    [15741529]     Ответить | Цитировать Сообщить модератору
 Re: [help] написать запрос MAX()  [new]
iap
Member

Откуда: Москва
Сообщений: 47052
iap
ilyaBS
iap,

дык дубликаты для 4го числа остаются
Что оставлять, если Name будут разные?

Ну, замените RANK() на ROW_NUMBER()
Они и есть разные.
По какому признаку надо оставить 'aaa'?
Почему не 'bbb' или 'ccc'?
17 мар 14, 21:10    [15741537]     Ответить | Цитировать Сообщить модератору
 Re: [help] написать запрос MAX()  [new]
iap
Member

Откуда: Москва
Сообщений: 47052
WITH CTE AS(SELECT N=RANK()OVER(PARTITION BY [log_date] ORDER BY [value] DESC),* FROM [Source])
SELECT * FROM CTE WHERE N=1;
17 мар 14, 21:14    [15741564]     Ответить | Цитировать Сообщить модератору
 Re: [help] написать запрос MAX()  [new]
iap
Member

Откуда: Москва
Сообщений: 47052
Ща придёт Добрый-Эх и даст ссылку на тему, в которой накидали десяток решений этой задачи.
Такие темы были и раньше.
17 мар 14, 21:16    [15741576]     Ответить | Цитировать Сообщить модератору
 Re: [help] написать запрос MAX()  [new]
west74
Member

Откуда: Челябинск
Сообщений: 76
можно так
select * from
( select log_date,MAX(VALUE) max_value from #source group by log_date) A
cross APPLY (select top(1) name from #source where log_date=A.log_date and VALUE=A.max_value) B

или как предлагал Выше iap (так ближе к решению автора)

WITH CTE AS(SELECT N=Row_number() OVER(PARTITION BY [log_date] ORDER BY [value] DESC),* FROM [#Source])
SELECT * FROM CTE WHERE N=1;
18 мар 14, 08:10    [15742793]     Ответить | Цитировать Сообщить модератору
 Re: [help] написать запрос MAX()  [new]
Добрый Э - Эх
Guest
iap
Ща придёт Добрый-Эх и даст ссылку на тему, в которой накидали десяток решений этой задачи.
Такие темы были и раньше.
Я пришел... Даю ссылку
18 мар 14, 11:44    [15743835]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить