Пусть в Access имеется такая таблица "Показания счетчиков воды":
Дата Счетчик1 Счетчик2
01.12.12 0 0
01.01.13 100 90
01.02.13 150 130
01.03.13 170 160
Надо узнать, сколько набежало в текущем месяце, т. е. вычесть значение счетчика в текущем месяце из значения счетчика в предыдущем.
Например, Итог1 на 01.02.13 будет равен 170 - 150 = 20.
Дата Итог1 Итог2
01.12.12 0 0
01.01.13 100 90
01.02.13 50 40
01.02.13 20 30
Другие языки программирования и технологии
[SQL-Access] Как вычесть текущую запись поля из предыдущего?
Основная проблема в том, как определить предыдущую запись. Можно, конечно, попробовать получить предыдущую дату с помощью DateAdd:
SELECT Дата, DateAdd("m", -1, Дата) AS Дата_prev FROM [Показания счетчиков воды] ;
Но при этом надо гарантировать, что все соседние даты в таблице различаются ровно на месяц. Лучше воспользоваться тем фактом, что предыдущая дата — это максимальная дата, не превышающая текущую:
SELECT Дата, (SELECT Max(Дата) FROM [Показания счетчиков воды] AS t2 WHERE t2.Дата < t1.Дата) AS Дата_пред FROM [Показания счетчиков воды] AS t1;
Определив предыдущую дату, легко получить значения счетчиков для неё:
SELECT Счетчик1, Счетчик2 FROM [Показания счетчиков воды] WHERE Дата = Дата_пред;
Теперь нужно скомпоновать в один запрос:
SELECT *
FROM (SELECT Дата, Счетчик1, Счетчик2, (SELECT Max(Дата) FROM [Показания счетчиков воды] AS t2 WHERE t2.Дата < t1.Дата) AS Дата_пред FROM [Показания счетчиков воды] AS t1) AS Тек LEFT JOIN [Показания счетчиков воды] AS Пред ON Тек. Дата_пред = Пред. Дата;
LEFT JOIN необходим, чтобы не потерялась первая запись, для которой нет предыдущего значения.
Теперь у нас есть таблица, в каждой записи которой есть данные на текущий и предыдущий месяц. Осталось вычислить требуемое. Надо только решить, что делать с самыми первыми показателями, для которых нет предыдущих. В этом случае, как мне кажется, разумно считать, что предыдущее показание равно текущему, так что итог получится нулевым. В итоге получаем такой запрос:
SELECT Тек. Дата AS Дата, Тек. Счетчик1 - Nz(Пред. Счетчик1,Тек. Счетчик1) AS Итог1, Тек. Счетчик2 - Nz(Пред. Счетчик2,Тек. Счетчик2) AS Итог2
FROM (SELECT Дата, Счетчик1, Счетчик2, (SELECT Max(Дата) FROM [Показания счетчиков воды] AS t2 WHERE t2.Дата < t1.Дата) AS Дата_пред FROM [Показания счетчиков воды] AS t1) AS Тек LEFT JOIN [Показания счетчиков воды] AS Пред ON Тек. Дата_пред = Пред. Дата;
SELECT Дата, DateAdd("m", -1, Дата) AS Дата_prev FROM [Показания счетчиков воды] ;
Но при этом надо гарантировать, что все соседние даты в таблице различаются ровно на месяц. Лучше воспользоваться тем фактом, что предыдущая дата — это максимальная дата, не превышающая текущую:
SELECT Дата, (SELECT Max(Дата) FROM [Показания счетчиков воды] AS t2 WHERE t2.Дата < t1.Дата) AS Дата_пред FROM [Показания счетчиков воды] AS t1;
Определив предыдущую дату, легко получить значения счетчиков для неё:
SELECT Счетчик1, Счетчик2 FROM [Показания счетчиков воды] WHERE Дата = Дата_пред;
Теперь нужно скомпоновать в один запрос:
SELECT *
FROM (SELECT Дата, Счетчик1, Счетчик2, (SELECT Max(Дата) FROM [Показания счетчиков воды] AS t2 WHERE t2.Дата < t1.Дата) AS Дата_пред FROM [Показания счетчиков воды] AS t1) AS Тек LEFT JOIN [Показания счетчиков воды] AS Пред ON Тек. Дата_пред = Пред. Дата;
LEFT JOIN необходим, чтобы не потерялась первая запись, для которой нет предыдущего значения.
Теперь у нас есть таблица, в каждой записи которой есть данные на текущий и предыдущий месяц. Осталось вычислить требуемое. Надо только решить, что делать с самыми первыми показателями, для которых нет предыдущих. В этом случае, как мне кажется, разумно считать, что предыдущее показание равно текущему, так что итог получится нулевым. В итоге получаем такой запрос:
SELECT Тек. Дата AS Дата, Тек. Счетчик1 - Nz(Пред. Счетчик1,Тек. Счетчик1) AS Итог1, Тек. Счетчик2 - Nz(Пред. Счетчик2,Тек. Счетчик2) AS Итог2
FROM (SELECT Дата, Счетчик1, Счетчик2, (SELECT Max(Дата) FROM [Показания счетчиков воды] AS t2 WHERE t2.Дата < t1.Дата) AS Дата_пред FROM [Показания счетчиков воды] AS t1) AS Тек LEFT JOIN [Показания счетчиков воды] AS Пред ON Тек. Дата_пред = Пред. Дата;
ГЕНИАЛЬНО!!!! ОГРОМНОЕ СПАСИБО!!!
Похожие вопросы
- Перечень допустимых функций в SQL-запросе ADO Jet 4.0 (MS Access)
- SQL и PHP. Access denied for user 'u3464476869_vid'@'12.3.4.23' to database 'u3464476869_Hyp'
- Вопрос по SQL в Access
- Скажите, в каких проектах что лучше использовать MS SQL-сервер, а в каких MS Access??
- Люди, знающие SQL, помогите сделать запрос.
- SQL (какие ?)
- Как в SQL найти запись по вхождению в заданное поле некоторого фрагмента текста?
- подскажите как средствами delphi добавить записи в подчененную таблицу Access!
- (delphi) Я заношу в массив ссылки на записи. Как получить доступ к полям записи?
- t-sql (курсоры и циклы - взаимозаменяемы?)