Пусть в 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 (курсоры и циклы - взаимозаменяемы?)
 
			