Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > СУБД, общие вопросы > SQL - предыдущее значение


Автор: Vit 1.7.2003, 04:24
Допустим есть таблица:


Num| ID | Date
-------------------
01 | AA |07/10/03
02 | BB |
03 | CC |08/10/03
04 | AA |03/10/03
05 | BB |


Надо сделать кверю, которая для всех ID='BB' в поле Date занесла значение из предыдущего рекорда (сортировка по Num), т.е. в конечном итоге хочу:

Num| ID | Date
-------------------
01 | AA | 07/10/03
02 | BB | 07/10/03
03 | CC | 08/10/03
04 | AA | 03/10/03
05 | BB | 03/10/03

База данных MS Access, но интересно послушать есть ли решение и для других баз данных (вариант с наложением курсора и перебиранием записей в цикле не предлагать - сам знаю, тем более в MS Access такое не работает)

Собственно эта задача была решена лет 5 назад при помощи QBE+Paradox - там такое делается не легко, а очень легко, но времена меняются - теперь MS Access + SQL актуален...

Автор: Nastya 3.7.2003, 15:42
Если поле с Id=bb стоит первым, какое занчение заносится в Date ?
Можно ли при решении задачи создавать промежуточные таблицы/запросы

Автор: Medved 4.7.2003, 11:15
Цитата
но интересно послушать есть ли решение и для других баз данных


PL/SQL - это можно сделать не напрягаясь, с помощью функции decode.

Автор: Cashey 4.7.2003, 13:37
Access я не знаю, но на FoxPro эта задача будет решаться так:
создается функция
Код

FUNCTION test
LPARAMETERS n
pMem=n
RETURN n


затем вызываем из программы

Код

PUBLIC pMem *объявляем публичную переменную
SELECT basetest *выбираем таблицу
GO top *переходим на первую запись
pMem = basetest.date *присваеваем переменной значение из первого поля
REPLACE date with; *вставляем
test(IIF(EMPTY(date),pMem,date));
all

Автор: vickr 4.7.2003, 13:50
Синтаксис SQL вряд ли позволит возвращать готовый результат в нужной форме. Необходимо изменять данные в процессе их отображения в форме - отслеживать событие Current, например, или как еще. С Access давненько не возился, но идея в голову приходит именно такая.
Vit
Если не получится - post here, можно будет подумать.

Автор: Vit 8.7.2003, 06:50
2 Nastya - ну это уже вопрос более простой, например можно ничего не делать, или вставить какое-то конкретное значение

2 Pegas - это понятно, в T-SQL это тоже реализуется относительно не сложно, но путём наложения курсора, что не очень приемлемо

2 Cashey - так же как и в любых системах, которые позволяют писать какой-никакой скрипт, а я хочу в запросе, в программе или процедурой Access я и сам могу реализовать (и реализовал уже, а вот чистым запросом как?)

2 vickr - форма здесь ни причём, я не Select делаю, а Update - никаких результатов никуда не выводится, над базой данных производится серия манипуляций, никакого интерфейса нет. В идеале - есть набор из сотни кверей которые просто запускаются и делают всё что нужно с файлом mdb, затем файл пересылается для дальнейшей обработке другому процессу на другом компьютере и возможно вообще не для меня а для какого-то клиента, который использует файл в своих собственных системах, собственно оговорены структуры таблиц и стандарты их заполнения, дальнейшее использование базы данных может быть очень разнообразным и не всегда под моим контролем... Но есть часть манипуляций которая не может быть выполненна через квери - это тот пример что я привёл, а также квери которые затрагивают 2 базы данных - одна на Access, другая на MS SQL Server - приходится программно проходить таблицы рекорд за рекордом, что мне не очень нравится.

Автор: gray_k 8.7.2003, 08:45
Насколько я знаю такое возможно в специализированных SQL (Oracle или MS-SQL). А стандартым запросом которые поддерживали бы все SQL-сервера скорее всего не получится. В Interbase такое не получится, так же как и в MySQL. Здесь надо писать хранимую процедуру. Причём для каждого сервера свою.

Автор: gray_k 8.7.2003, 08:49
vit
Цитата
приходится программно проходить таблицы рекорд за рекордом, что мне не очень нравится

И какая разница в конце концов. Ведь такой запрос, который ты хочешь сделать ИМХО всё равно просмотрит все записи в таблице. В Interbase есть такая штука как план запроса. В нём показываются все действия над базой, которые делает запрос. НЕ знаю есть ли такое в MS-SQL, но если есть то посмотрев его по идее ты должен увидеть, что происходит полный перебор таблицы. Просто их надо оптимально проиндексировать.

Автор: Medved 8.7.2003, 08:50
ИМХО подругому никак.....

Автор: Cashey 8.7.2003, 19:54
Vit, SQL-запрос по своей сути является циклом т.е. все равно бегает по всей базе и команда Update присваевает значение ячейке только той записи на которой находится. Сам понимаешь, предыдущее значение надо где-то запомнить, но с пременными SQL не работает. Вот и остается пропускать через него функцию. По другому я не представляю как можно зделать, даже чисто теоритически.

Автор: Лкшы 9.7.2003, 08:40
За другие базы не знаю, в Interbase Update будет выглядеть так:
update TAB T1 set D1.DATA=(select T2.DATA from TAB T2 where T2.Num=(select max(T3.Num) from TAB T3 where T3.Num<T1.Num)) where T1.ID='BB'
Результат получается как просили. Или я чего не понимяю?

Автор: Vit 9.7.2003, 15:29
2 Лкшы - спасибо, похоже должно работать для многих баз данных, но к сожалению в MS Access не поддерживаются запросы вида:

Update
Set MyField=(select...)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)