Форум: "Базы";
Текущий архив: 2008.04.20;
Скачать: [xml.tar.bz2];
ВнизРасчет среднего значения. Найти похожие ветки
← →
Neket (2007-11-17 13:17) [0]Как расчитать среднее только по первым двум значениям? Т.е. Имеется к примеру такая табличка:
Name | Value | Date
Name1 | 15 | 15.07.2006
Name1 | 14 | 20.07.2006
Name1 | 11 | 12.07.2006
Name1 | 7 | 11.07.2006
Name2 | 45 | 01.07.2006
Name2 | 37 | 06.07.2006
Name2 | 25 | 16.07.2006
Name2 | 18 | 26.07.2006
..... ну и так далее
И как теперь вычислить среднее значение AVG только первых двух значений. Т.е. чтобы была к примеру такая табличкаName | Value_AVG
Name1 | 14.5
Name2 | 41
..... ну и так далее
P.S. Подозреваю что необходимо использовать аналитический функции, но к сожалению я с ними очень не знаком поэто му решил к вам обратиться. Кто может подскажите пожалуйста :-)
← →
Kolan © (2007-11-17 13:30) [1]Нужно сгрупировать.
Table:
Name | Value | Date
Name1 | 15 | 15.07.2006
Name1 | 14 | 20.07.2006
Name1 | 11 | 12.07.2006
Name1 | 7 | 11.07.2006
Name2 | 45 | 01.07.2006
Name2 | 37 | 06.07.2006
Name2 | 25 | 16.07.2006
Name2 | 18 | 26.07.2006SELECT Name, AVG(Value) AS Value_AVG
FROM Table
Group BY Name
← →
Neket (2007-11-17 13:35) [2]Да но в это случае расчет среднего будет произодиться по всем четырем начениям, а задача стоит в том чтобы расчитать только по первым двум значениям. Т.е. NAME1 только за 15.07.2006 и 20.07.2006, NAME2 только за 11.07.2006 и 01.07.2006
← →
Kolan © (2007-11-17 14:09) [3]> по первым двум значениям
Ну сделайте нужный SELECT.SELECT * FROM Table
WHERE (Date = "2006-07-15") OR (…)
А уже этот SELECT — см. [1]
← →
sniknik © (2007-11-17 14:12) [4]> а задача стоит в том чтобы расчитать только по первым двум значениям.
значит подбери условие которое отбирает только первые два... (по какому признаку первые?... порядковые номера так эфемерны, и обманчивы...)
> Т.е. NAME1 только за 15.07.2006 и 20.07.2006, NAME2 только за 11.07.2006 и 01.07.2006
ну вот как вариант и пиши это в условии отбора, только в SQL -
WHERE Name="Name1" AND Date=... и тд....
← →
Neket (2007-11-17 14:21) [5]Дело в том что даты могут быть разными а слолбец value отсортирован по убыванию. И задача посчитать среднее первых двух максимальных значений.
Т.е. Даты могуть быть абсолютоно разными... Это я писал для примера...
У меня есть селект который выбирает максимальные значения VALUE за месяц по недельно. И необходимо вычислить среднее значния дву максимальных значений value за четыре недели. Витеевато наверное объяснил. Извините. :-)
← →
Kolan © (2007-11-17 14:50) [6]> И необходимо вычислить среднее значния дву максимальных
> значений value за четыре недели.
Вот и савтено условие.
Какая СУБД? SQL Server 2005 съестSELECT TOP N
(кажется)…
← →
Neket (2007-11-17 14:55) [7]Oracle.... SELECT TOP N не прокатит
← →
Neket (2007-11-17 15:22) [8]Можно даже не много перфразировать задачу...
Как имея такую таблицу:
tabel1
Name | Value | Date
Name1 | 15 | 15.07.2006
Name1 | 14 | 20.07.2006
Name1 | 11 | 12.07.2006
Name1 | 7 | 11.07.2006
Name2 | 45 | 01.07.2006
Name2 | 37 | 06.07.2006
Name2 | 25 | 16.07.2006
Name2 | 18 | 26.07.2006
..... ну и так далее
получить такую
Table2
Name | Value | Date
Name1 | 15 | 15.07.2006
Name1 | 14 | 20.07.2006
Name2 | 45 | 01.07.2006
Name2 | 37 | 06.07.2006
..... ну и так далее
Т.е. Чтобы выводились только первые два значения каждого name из table1
← →
Kolan © (2007-11-17 15:46) [9]Если я правильно понимаю задачу, то тебе надо научится выбирать две верхние строки в отсортированном наборо данных. Как сделать это в ORACLE я незнаю. Но точно уверен, что это можно сделать написав соотв хрон процедуру. Кажется в ORACLE язык называется PL SQL. Но(!) в правильности такого решения я не уверен…
← →
Neket (2007-11-17 16:03) [10]Да все верно... В оракле самый простой способ это написать процедуру, но задача состоит имено в том чтобы вычислить значения при помощи обычного select-а.
← →
Kolan © (2007-11-17 16:06) [11]Может так:
SELECT * FROM Table
WHERE
(Value = (SELECT Max(Value) FROM Table))
OR (Value = (
SELECT Max(Value) FROM Table WHERE Value <> (SELECT Max(Value) FROM Table)))
Это идея…
← →
Kolan © (2007-11-17 16:11) [12]Иными словами:
DECLARE @MaxValue int;
DECLARE @SecondFromMax int;
SET @MaxValue = SELECT Max(Value) FROM Table;
SET @SecondFromMax = SELECT Max(Value) FROM Table WHERE Value <> @MaxValue;
SELECT * FROM Table
WHERE (Value = @MaxValue) OR (Value = @SecondFromMax)
← →
Neket (2007-11-17 16:41) [13]Спасибо... Но уже сам догадался... :-) Теперь другой вопрос... :-( Так сложилось что колличество значений не стаическое а динамическое. Т.е. Не фиксировано 4 значения каждого Name, а колеблится от 1 до 4. В связи с этим необходимо если колличество значений name<>N, тогда не обрабатывать эти строки...
иными словами в селект
SELECT * FROM Table
WHERE
(Value = (SELECT Max(Value) FROM Table))
OR (Value = (
SELECT Max(Value) FROM Table WHERE Value <> (SELECT Max(Value) FROM Table)))
необходимо добавить условие не обрабатывать name-ы если их колличество не равно N, где N - может быть равно от 2 до 4.
← →
Kolan © (2007-11-17 16:48) [14]
> Т.е. Не фиксировано 4 значения каждого Name, а колеблится
> от 1 до 4. В связи с этим необходимо если колличество значений
> name<>N, тогда не обрабатывать эти строки…
Это не понял…
> необходимо добавить условие не обрабатывать name-ы если
> их колличество не равно N, где N — может быть равно от 2
> до 4.
А тут что трудно?SELECT Name
FROM Tabel
WHERE Count(*) BETWEEN 2 AND 4
Или я не понял вопрос…
GROUP BY Name
← →
Anatoly Podgoretsky © (2007-11-17 17:01) [15]Надо тор 2 использовать во внутреннем селекта, а по нему уже брать среднее.
← →
Neket (2007-11-17 17:12) [16]А есть какая нибудь функция в SQL которой задаеш имя столбца, значение какое либо из этого столбца а она возвращает сколько раз встречается это значение. Т.е.
tabel1
Name | Value | Date
Name1 | 15 | 15.07.2006
Name1 | 14 | 20.07.2006
Name2 | 45 | 01.07.2006
Name2 | 37 | 06.07.2006
Name2 | 25 | 16.07.2006
Count_Zna4(Tabel1,"NAME1") =2
Count_Zna4(Tabel1,"NAME2") =3
ну или чегонибудь похожее...
← →
Anatoly Podgoretsky © (2007-11-17 18:00) [17]> Neket (17.11.2007 17:12:16) [16]
Есть, это count
← →
Johnmen © (2007-11-17 22:14) [18]Написание ХП обеспечит максимум прозрачности, скорости и функциональной гибкости. В данном случае.
← →
sdts (2007-11-17 22:19) [19]
> Johnmen © (17.11.07 22:14) [18]
> Написание ХП обеспечит максимум прозрачности, скорости и
> функциональной гибкости. В данном случае.
эта, а есть противоположные случаи?
← →
Johnmen © (2007-11-17 22:27) [20]
> эта, а есть противоположные случаи?
Для простых выборок разве что.
← →
Petr V. Abramov © (2007-11-17 22:34) [21]> Подозреваю что необходимо использовать аналитический функции
100% правильно понимаешь.
понимаю, их много, но сейчас за тебя смотреть лень, а навскидку не помню
← →
Neket (2007-11-18 09:57) [22]В первом случае как раз воспользовался аналитической функцией совместно с max().
select
name,
max(value_avg)
from
(select
name,
avg(value) OVER (ORDER BY value rows BETWEEN 1 PRECEDING AND CURRENT ROW) as value_avg
from
tabel1
group by name) name_AVG
group by name
Как-то так :-)
Но вот теперь стал вопрос как подвизать сюда этот count или похожую функцию которая позволит не рассматривать в TABLE значения name если его колличесто меньше N где N можно задавать произвольно.
← →
Кщд © (2007-11-19 08:49) [23]Neket (18.11.07 09:57) [22]
> select
> name,
> avg(value) OVER (ORDER BY value rows BETWEEN 1 PRECEDING
> AND CURRENT ROW) as value_avg
> from
> tabel1
без использования partition by результат, в общем случае, будет не тот, что Вам нужен
← →
Кщд © (2007-11-19 08:59) [24]если так сильно хочется аналитики, то
with t as (
select 1 as ID, 1 as val from dual
union all
select 1 as ID, 2 as val from dual
union all
select 1 as ID, 3 as val from dual
union all
select 2 as ID, 1 as val from dual
union all
select 2 as ID, 2 as val from dual
)
select *
from
(
select id,
avg(val) over (partition by id order by val) avg_val,
row_number() over(partition by id order by val) rn,
count(*) over (partition by id) cnt
from t
) t2
where t2.rn = 1
and t2.cnt = 2
← →
Neket (2007-11-19 14:54) [25]Все всем спасибо... Все сделал. Все заработало.
← →
Кщд © (2007-11-20 09:22) [26]>Neket (19.11.07 14:54) [25]
ради интереса: можно увидеть финальный вариант?
← →
имя (2007-11-24 21:26) [27]Удалено модератором
← →
Andrey © (2007-11-26 09:33) [28]
select t1.name,
(select avg(t2.value)
from tbl t2
where t2.name = t1.name
and rownum <= 2
order by t2.value desc)
from tbl t1
group by t1.name
Нэ?
Хотя конечно через хранимую лучше будет.
← →
Кщд © (2007-11-27 10:47) [29]>Andrey © (26.11.07 09:33) [28]
>and rownum <= 2
в общем случае, запрос будет возвращать ерунду)
← →
Кщд © (2007-11-27 10:51) [30]поясню - выполните:
[]
select rownum, t2.*
from tbl t2
order by t2.value desc
← →
Andrey © (2007-11-27 11:34) [31]>Кщд © (27.11.07 10:51) [30]
Ыть, промазал. Никогда особо не использовал rownum, по этому не знал некоторых тонкостей: "Значение ROWNUM присваивается строке после завершения фазы обработки предикатов запроса, но перед выполнением каких-либо сортировок и агрегирований" http://www.oracle.com/global/ru/oramag/mayjune2007/w_dev_asktom56.html
← →
Кщд © (2007-11-27 12:35) [32]>Andrey © (26.11.07 09:33) [28]
теперь самое время подумать о кол-ве FTS)
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2008.04.20;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.046 c