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

Откуда:
Сообщений: 69
Добрый день. Возникла необходимость решить следующую задачу.
Имеется таблица следующего вида:
ID_Point DateTime Value
1 2011-07-01 00:00:00 0.0043
1 2011-07-01 00:30:00 0.0056
и т.д.

И таблица, хранящая имена пойнтов:
ID_Point Name
1 aaa
и т.д.

Необходимо сформировать запрос, результатом которого будет выборка вида
ID_Point Name DateTime Value
1 aaa 2011-07-01 00:00:00 (0.0043+0.0056)


Т.е. сложить между собой значения получасовых измерений в часовое. Так по
количеству записей более нескольких десятков тысяч.
Привел упрощенную форму базы, помимо этого в результирующую выборку необходимо
объединением включать еще несколько таблиц...
На данных момент задачу решил с использованием курсора, но это достаточно сильно грузит систему. Как можно решить это запросом?

Буду очень благодарен за помощь!
8 авг 11, 16:15    [11086825]     Ответить | Цитировать Сообщить модератору
 Re: Объединение таблиц с агрегированием  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
Joseph_5,

GROUP BY + SUM
8 авг 11, 16:19    [11086847]     Ответить | Цитировать Сообщить модератору
 Re: Объединение таблиц с агрегированием  [new]
Glory
Member

Откуда:
Сообщений: 104751
Округлить datetime до целого часа ?
8 авг 11, 16:20    [11086851]     Ответить | Цитировать Сообщить модератору
 Re: Объединение таблиц с агрегированием  [new]
Joseph_5
Member

Откуда:
Сообщений: 69
iap
Проблема в том, что в списке выбираемых полей, при агрегировании, каждое из указанных полей должно участвовать в операции агрегирования. В данном же случае поле ID_Point в агрегировании участвовать не должно.. По большому счету вместо поля ID_Point у меня результат составной выборки, просто здесь я написал пример упрощенный
8 авг 11, 16:22    [11086871]     Ответить | Цитировать Сообщить модератору
 Re: Объединение таблиц с агрегированием  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
Joseph_5
iap
Проблема в том, что в списке выбираемых полей, при агрегировании, каждое из указанных полей должно участвовать в операции агрегирования. В данном же случае поле ID_Point в агрегировании участвовать не должно.. По большому счету вместо поля ID_Point у меня результат составной выборки, просто здесь я написал пример упрощенный
Какие же значения полей, не участвующих в агрегировании,
должны присутствовать в результате?
Ведь их же много для каждой строки получается.

В говнокоде для них можно функцию MIN() применить, но это просто уродство какое-то, если необдуманно так написать.
Если же результат агрегирования надо продублировать на каждой строке, то есть же SUM()OVER()
8 авг 11, 16:27    [11086926]     Ответить | Цитировать Сообщить модератору
 Re: Объединение таблиц с агрегированием  [new]
Joseph_5
Member

Откуда:
Сообщений: 69
Glory,

Не совсем понял Ваш совет... Если можно, чуть подробнее.

Glory, опишу задачу полностью. Просто так становится очень громоздко и неудобн для чтения
Имеется 4-и таблицы.
1) У первой таблицы с названием PointMains имеются поля
ID_PP(номер параметра точки учета);DT(дата и время проведенных измерений);Val(измеренное значение).
Пример записей:


ID_PP DT Val
1 2011-07-01 00:00:00 0.04
1 2011-07-01 00:30:00 0.05
2 2011-07-01 00:00:00 0.2
2 2011-07-01 00:30:00 0.3


2)Вторая - PointParams. Имеет поля:
ID_PP(номер параметра точки учета, связано с таблице PointMains), ID_Point (номер точки учета); ID_Param(ID параметра)

Пример:
ID_PP ID_Point ID_Param
1 9 4
2 9 8

3) Points
Поля:
ID_point; PointName

Пример:
ID_Point PointName
9 счётчик 1


4)PointParamTypes
Поля ID_Param(ID параметра), ParamName(имя параметра)
Пример:
ID_Param ParamName
4 Активная энергия
8 Реактивная энергия

Необходимо, чтобы в конечной выборке все выглядело следующим образом:
ID_Point PointName MeasureDate Value1 Value2

Где MeasureDate - час измерения; Value1 - измеренная за час активная энергия(т.е. сумма значений Val из соответствующих записей таблицы PointMains);
Value 2 - измеренная за час реактивная энергия.
Пример (полученный с использованием курсора для суммирования и вставки):
ID_Point PointName MeasureDate Value1 Value2
9 счетчик1 2011-07-01 00:00:00.000 0.09 0.5
8 авг 11, 16:51    [11087093]     Ответить | Цитировать Сообщить модератору
 Re: Объединение таблиц с агрегированием  [new]
Joseph_5
Member

Откуда:
Сообщений: 69
Прошу прощения, форма лишние пробелы хавает=( неформатированный текст получился.
Вот такая задача, прошу подсказать, господа профессионалы...
8 авг 11, 16:52    [11087098]     Ответить | Цитировать Сообщить модератору
 Re: Объединение таблиц с агрегированием  [new]
Glory
Member

Откуда:
Сообщений: 104751
Joseph_5
Glory,

Не совсем понял Ваш совет... Если можно, чуть подробнее.

Вы знаете, что такое округление ?
Можете время округлять с нужной точностью ?
8 авг 11, 16:58    [11087130]     Ответить | Цитировать Сообщить модератору
 Re: Объединение таблиц с агрегированием  [new]
Joseph_5
Member

Откуда:
Сообщений: 69
Glory,

Безусловно, но как при этом решится проблема суммирования получасовых значений?
8 авг 11, 17:00    [11087143]     Ответить | Цитировать Сообщить модератору
 Re: Объединение таблиц с агрегированием  [new]
Glory
Member

Откуда:
Сообщений: 104751
Joseph_5
Glory,

Безусловно, но как при этом решится проблема суммирования получасовых значений?

Ну так что будет после округления 2011-07-01 00:30:00 до целого часа ?
8 авг 11, 17:03    [11087165]     Ответить | Цитировать Сообщить модератору
 Re: Объединение таблиц с агрегированием  [new]
Joseph_5
Member

Откуда:
Сообщений: 69
Glory,
Я делаю так
set @DT = dateadd(Minute,-DatePART(minute,@DT),@DT)
И получим число + 00:00:00
Но что толку?
8 авг 11, 17:24    [11087311]     Ответить | Цитировать Сообщить модератору
 Re: Объединение таблиц с агрегированием  [new]
Glory
Member

Откуда:
Сообщений: 104751
Если из набора

1 2011-07-01 00:00:00 0.0043
1 2011-07-01 00:30:00 0.0056

после округления получится

1 2011-07-01 00:00:00 0.0043
1 2011-07-01 00:00:00 0.0056

то в чем проблема с группировкой и суммированием ?
8 авг 11, 17:27    [11087327]     Ответить | Цитировать Сообщить модератору
 Re: Объединение таблиц с агрегированием  [new]
Joseph_5
Member

Откуда:
Сообщений: 69
Glory,

Проблема в том, что после этого производя group by DT мы должны будем агрегировать так же и поле ID_PP с которым никаких манипуляций проделывать не нужно. При всем при этом, по данному полю мы должны делать join с другой таблицей и поэтому отбросить мы его никак не можем!
8 авг 11, 17:29    [11087338]     Ответить | Цитировать Сообщить модератору
 Re: Объединение таблиц с агрегированием  [new]
Glory
Member

Откуда:
Сообщений: 104751
Joseph_5
мы должны будем агрегировать так же и поле ID_PP

Почему это "должны" ?
8 авг 11, 17:30    [11087353]     Ответить | Цитировать Сообщить модератору
 Re: Объединение таблиц с агрегированием  [new]
Joseph_5
Member

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

Спасибо за совет, но как-раз таки min() применять точно нельзя, недопустима ошибка в значении поля ID_PP ни в коем случае..
т.е. фактически из двух записей получасовок надо получить одну часовку, но при этом поле ID_PP должно сохранить свое значение (одинаковое для обоих часовок). Тут , вроде как, подходит AVG() - вреда не принесет, но опять таки, если у нас с порядком записей в таблице все хорошо, но нужно понимать, что есть и огрызки - лишь отдельные получасовки, и агрегирование происходит неправильно=(.
например если подряд идут записи

ID_PP DT
1 00:00:00
2 00:30:00

С использованием case получаем результат запроса
ID_PP DT
1 00:00:00
2 00:00:00
После этого Group By DT
и замечательно пролетаем с полем ID_PP... но я уверен, что это можно сделать средствами выборки, без курсора... просто у меня не хватает знаний...
8 авг 11, 17:33    [11087372]     Ответить | Цитировать Сообщить модератору
 Re: Объединение таблиц с агрегированием  [new]
Joseph_5
Member

Откуда:
Сообщений: 69
Glory,

Но как же select ID_PP, CASE DATEPART(MINUTE, DT) WHEN 30 THEN DATEADD(MINUTE,-30,DT) ELSE DT END as MeasureDate Group By MeasureDate

Каждое из полей должно быть включено в агрегирующую функцию.. разве нет?
8 авг 11, 17:35    [11087390]     Ответить | Цитировать Сообщить модератору
 Re: Объединение таблиц с агрегированием  [new]
Glory
Member

Откуда:
Сообщений: 104751
Joseph_5
Каждое из полей должно быть включено в агрегирующую функцию.. разве нет?

Или в GROUP BY
8 авг 11, 17:38    [11087419]     Ответить | Цитировать Сообщить модератору
 Re: Объединение таблиц с агрегированием  [new]
Joseph_5
Member

Откуда:
Сообщений: 69
Glory,

т.е. решением моей проблемы будет такой запрос:

select PM.MeasureDate, PM.ID_PP ,sum(PM.Val) From
(select top 500 ID_PP, Case DATEPART(MINUTE,DT) WHEN 30 THEN DATEADD(MINUTE,-30,DT) ELSE DT END as MeasureDate ,Val from PointMains) as PM
group By PM.MeasureDate, PM.ID_PP


Тут у меня некоторый пробел, не могли бы Вы объяснить, как в таком случае будет происходить агрегирование?
8 авг 11, 17:47    [11087521]     Ответить | Цитировать Сообщить модератору
 Re: Объединение таблиц с агрегированием  [new]
Glory
Member

Откуда:
Сообщений: 104751
Так, как вы хотели
набор
1 2011-07-01 00:00:00 0.0043
1 2011-07-01 00:30:00 0.0056

превратится в
1 2011-07-01 00:00:00 (0.0043+0.0056)
8 авг 11, 17:49    [11087541]     Ответить | Цитировать Сообщить модератору
 Re: Объединение таблиц с агрегированием  [new]
Joseph_5
Member

Откуда:
Сообщений: 69
Glory,

Спасибо! Решение, вроде бы, оказалось на поверхности! Очень благодарен за консультацию.
8 авг 11, 17:51    [11087560]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить