Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Базы данных
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 26.02.2014, 18:44
chugastr chugastr вне форума
Прохожий
 
Регистрация: 26.02.2014
Сообщения: 7
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Разница двух соседних записей одного поля с результатом в вычисляемое поле

Добрый день
Помогите решить следующую задачу
Имеется таблица БД Access с полями:
key (ключевое поле)Date, V
1 01.01.2014 0
2 02.01.2014 145
3 03.01.2014 302
4 04.01.2014 458
5 05.01.2014 621

Date - дата, V - показания счетчика воды

Как с помощью ADOQuery создать вычисляемое поле, в каждой записи которого будет разница значений следующей записи поля V (если она есть) и текущей записи поля V?
Под соседними записями подразумевается две соседние даты. Я делаю SQL-запрос, а при выводе в таблицу EhGrid сортирую по возрастанию даты.

Результат должен получиться такой:
key (ключевое поле), Date, V, dV
1 01.01.2014 0 145
2 02.01.2014 145 157
3 03.01.2014 302 156
4 04.01.2014 458 163
5 05.01.2014 621

dV - вычисляемое поле со значением суточного потребления воды

Заранее спасибо за помощь

Последний раз редактировалось chugastr, 27.02.2014 в 13:43.
Ответить с цитированием
  #2  
Старый 27.02.2014, 06:36
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,036
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Ну, например, с помощью Window Functions. Хотя что-то я не уверен, что Access их поддерживает. Соответсвенно, придется извращаться с self-join. В общем, проблема в том, что порядок записей в возвращаемом результате никто не гарантирует. Поэтому клиентский код будет для таких вычислений проходиться по всей таблице для поиска нужной записи, либо сортировка (нужная) будет "прибита гвоздями". Ни один из этих вариантов не является хорошим.
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
chugastr (03.03.2014)
  #3  
Старый 27.02.2014, 09:15
Аватар для Mrak
Mrak Mrak вне форума
Местный
 
Регистрация: 26.01.2013
Адрес: МО
Сообщения: 438
Версия Delphi: XE2
Репутация: 17
По умолчанию

Если задача позволяет, можно делать этот пересчет при вставке новой записи

з.ы. Почему-то приходит на ум функция avg, может в дальнейшем поможет)
__________________
Я за здоровый экстрим!
Спасибо за "спасибо")
Ответить с цитированием
Этот пользователь сказал Спасибо Mrak за это полезное сообщение:
chugastr (03.03.2014)
  #4  
Старый 27.02.2014, 11:07
AlexSku AlexSku вне форума
Специалист
 
Регистрация: 07.05.2007
Адрес: Москва
Сообщения: 884
Репутация: 21699
По умолчанию

Под следующей надо понимать запись, у которого дата на сутки больше. Через SELECT делается просто.
Ответить с цитированием
  #5  
Старый 27.02.2014, 13:47
chugastr chugastr вне форума
Прохожий
 
Регистрация: 26.02.2014
Сообщения: 7
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от AlexSku
Под следующей надо понимать запись, у которого дата на сутки больше. Через SELECT делается просто.
Именно так, на сутки больше
А можно по-подробнее, как сформировать нужный SQL-запрос с Select? А то я в этом вопросе совсем слаб

Последний раз редактировалось chugastr, 27.02.2014 в 13:50.
Ответить с цитированием
  #6  
Старый 27.02.2014, 13:54
Аватар для Yurk@
Yurk@ Yurk@ вне форума
Специалист
 
Регистрация: 07.09.2007
Адрес: Украина, г. Днепропетровск
Сообщения: 892
Версия Delphi: 7 + ОгнеПтица
Репутация: выкл
По умолчанию

попробуй так
Код:
SELECT t.key, t.date, t.v, (COALESCE(t1.v, 0) - t.v) dv
FROM table t
  LEFT JOIN table t1 ON t1.key = t.key + 1
за основу "следующей строки" взято ключевое поле key, но можно ориентироваться и по полу date
__________________
Поживу - увижу, Доживу - узнаю, Выживу - учту.
[P.S.]->Выражая благодарность за помощь - Вы получаете шанс на помощь в следующий раз
Ответить с цитированием
Этот пользователь сказал Спасибо Yurk@ за это полезное сообщение:
chugastr (03.03.2014)
  #7  
Старый 28.02.2014, 17:07
chugastr chugastr вне форума
Прохожий
 
Регистрация: 26.02.2014
Сообщения: 7
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Yurk@
попробуй так
Код:
SELECT t.key, t.date, t.v, (COALESCE(t1.v, 0) - t.v) dv
FROM table t
  LEFT JOIN table t1 ON t1.key = t.key + 1
за основу "следующей строки" взято ключевое поле key, но можно ориентироваться и по полу date

Попробовал так, но не получилось.
При Datamodule1.ADOQuery1.Activ:=true, выдает ошибку "Неопознанная ошибка"
Ответить с цитированием
  #8  
Старый 28.02.2014, 23:42
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от chugastr
Попробовал так, но не получилось.
При Datamodule1.ADOQuery1.Activ:=true, выдает ошибку "Неопознанная ошибка"
У меня в MS Access 2003 вот так нормально работает:
PHP код:
SELECT t.keyt.datet.v, (t1.t.v) AS dV
FROM 
[tablet
  LEFT JOIN 
[tablet1 ON t1.key t.key 
Ответить с цитированием
Этот пользователь сказал Спасибо poli-smen за это полезное сообщение:
chugastr (03.03.2014)
  #9  
Старый 03.03.2014, 17:31
chugastr chugastr вне форума
Прохожий
 
Регистрация: 26.02.2014
Сообщения: 7
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от poli-smen
У меня в MS Access 2003 вот так нормально работает:
PHP код:
SELECT t.keyt.datet.v, (t1.t.v) AS dV
FROM 
[tablet
  LEFT JOIN 
[tablet1 ON t1.key t.key 

Спасибо за помощь

При таком запросе выдает "Ядро базы данных Microsoft Jet не может найти входную таблицу или запрос 'table'". Если убираю [table], то тогда так же ругается на t1.
А вообще, поле dV в БД я должен вручную создать или это вычисляемое поле, которое создается только во время запроса? Таблица t1 виртуальная, или ее надо предварительно создать в БД? Нужно ли прописывать что-то в процедуре события OnCalcFields?


Программу пишу в Delphi 7, компонент TADOQuery. Поставщик OLE DB: Microsoft Jet 4.0 OLE DB Provider

Последний раз редактировалось chugastr, 03.03.2014 в 17:58.
Ответить с цитированием
  #10  
Старый 03.03.2014, 17:35
icWasya icWasya вне форума
Местный
 
Регистрация: 09.11.2010
Сообщения: 499
Репутация: 10
По умолчанию

Вместо [table] нужно подставить Вашу таблицу
Ответить с цитированием
  #11  
Старый 03.03.2014, 17:47
chugastr chugastr вне форума
Прохожий
 
Регистрация: 26.02.2014
Сообщения: 7
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от icWasya
Вместо [table] нужно подставить Вашу таблицу
так моя таблица там уже прописана: t
Ответить с цитированием
  #12  
Старый 03.03.2014, 18:04
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от chugastr
так моя таблица там уже прописана: t
Нет. В этом запросе t является не именем реальной таблицы, а алиасом на неё.
У тебя что, действительно в базе данных у этой таблицы имя "t"?
Если так, то тебе в качестве алиасов нужно использовать другие слова, например:
PHP код:
SELECT xxxx.keyxxxx.datexxxx.v, (yyyy.xxxx.v) AS dV
FROM 
[txxxx
  LEFT JOIN 
[tyyyy ON yyyy.key xxxx.key 
Ответить с цитированием
Этот пользователь сказал Спасибо poli-smen за это полезное сообщение:
chugastr (03.03.2014)
  #13  
Старый 03.03.2014, 18:17
chugastr chugastr вне форума
Прохожий
 
Регистрация: 26.02.2014
Сообщения: 7
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от poli-smen
У тебя что, действительно в базе данных у этой таблицы имя "t"?

Да, я протупил

Получилось!
Большое человеческое спасибо! А где можно почитать по синтаксису и командам/функциям SQL для чайников?
Ответить с цитированием
  #14  
Старый 03.03.2014, 18:40
chugastr chugastr вне форума
Прохожий
 
Регистрация: 26.02.2014
Сообщения: 7
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Если шаг между записями один день, то запрос будет таким:
t1.date = t.date + 1
это получилось

А если шаг между записями будет один час, то как будет выглядеть запрос? Что надо написать вместо "+ 1" ?

key (ключевое поле)Date, V
1 01.01.2014 01:00:00 0
2 01.01.2014 02:00:00 145
3 01.01.2014 03:00:00 302
4 01.01.2014 04:00:00 458
5 01.01.2014 05:00:00 621
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 22:36.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter