Гость
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Выбрать с таблицы записи по последней дате / 17 сообщений из 17, страница 1 из 1
08.03.2010, 22:30
    #36507900
Ewgeny911
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать с таблицы записи по последней дате
Здравствуйте! Не подскажите как с помощью SQL запроса отобрать последние по дате записи из таблицы? Проограмма на Delphi. Используется стандартный Query с вкладки BDE. Вообщем, есть две таблицы: основная (MOTION.DBF) и справочник отделений (SPRAVOTDEL.DBF).
В таблице MOTION.DBF несколько полей: Дата записи (DATERECORD), код отделения (CD), количество человек (SOSTVSE).
В таблице SPRAVOTDEL.DBF - поле KEYMINE - это тоже самое, что поле CD в MOTION.DBF, SORTNUM - для сортировки.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
Таблица MOTION.DBF:
DATERECORD	CD	SOSTVSE
 11 . 10 . 2009 	 112 	 2 
 11 . 10 . 2009 	 282 	 9 
 11 . 10 . 2009 	 111 	 2 
 12 . 10 . 2009 	 111 	 5 
 12 . 10 . 2009 	 252 	 3 
 12 . 10 . 2009 	 112 	 5 
 12 . 10 . 2009 	 242 	 8 
 12 . 10 . 2009 	 112 	 7 
 13 . 10 . 2009 	 111 	 6 
 13 . 10 . 2009 	 242 	 1 
 13 . 10 . 2009 	 262 	 4 

Таблица SPRAVOTDEL.DBF:
KEYMINE	NAME	SORTNUM
 111 	Терапия	 1 
 112 	Хирургия	 2 
 242 	Неврология	 3 
 252 	Урология	 4 
 262 	Педиатрия	 5 
 282 	Кардиология	 6 
Нужно отобрать записи из таблицы MOTION, записи но не всех отделений, а например только тех, которые в справочнике SPRAVOTDEL в диапазоне по полю SORTNUM от 2 до 5. Т.е. в данном случае 112, 242, 252, 262. Нужно отобрать по одной записи (из таблицы MOTION) для каждого из этих отделений. Но для каждого отделения эта запись должна быть последней по дате. (В реальном справочнике около 60 отделений, там они разбиты по блокам и нужно получить данные по блоку - для этого и используется поле SORTNUM. Записей в MOTION около 40000).
В данном случае должны быть отобраны записи:

Код: plaintext
1.
2.
3.
4.
5.
DATERECORD	CD	SOSTVSE
 12 . 10 . 2009 	 112 	 7 
 12 . 10 . 2009 	 252 	 3 
 13 . 10 . 2009 	 242 	 1 
 13 . 10 . 2009 	 262 	 4 

Т.е. сколько отделений в выбранном диапазоне справочника, столько и должно быть записей, но каждая из этих записей должна быть последняя по дате.
...
Рейтинг: 0 / 0
08.03.2010, 23:34
    #36507943
thunder2
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать с таблицы записи по последней дате
Ewgeny911,

А самому мозг не напрячь, студент блин ?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
CREATE TABLE motion FREE ( datarecord d, cd n( 3 ),sostvse n( 1 ))
INSERT INTO motion VALUES ({^ 2009 - 10 - 11 }, 112 , 2 )
INSERT INTO motion VALUES ({^ 2009 - 10 - 11 }, 282 ,	 9 )
INSERT INTO motion VALUES ({^ 2009 - 10 - 11 }, 111 ,	 2 )
INSERT INTO motion VALUES ({^ 2009 - 10 - 12 }, 111 ,	 5 )
INSERT INTO motion VALUES ({^ 2009 - 10 - 12 }, 252 ,	 3 )
INSERT INTO motion VALUES ({^ 2009 - 10 - 12 }, 112 ,	 5 )
INSERT INTO motion VALUES ({^ 2009 - 10 - 12 }, 242 ,	 8 )
INSERT INTO motion VALUES ({^ 2009 - 10 - 12 }, 112 ,	 7 )
INSERT INTO motion VALUES ({^ 2009 - 10 - 13 }, 111 ,	 6 )
INSERT INTO motion VALUES ({^ 2009 - 10 - 13 }, 242 ,	 1 )
INSERT INTO motion VALUES ({^ 2009 - 10 - 13 }, 262 ,	 4 )

CREATE TABLE SPRAVOTDEL FREE ( KEYMINE	n( 4 ),NAME c( 20 ),	SORTNUM n( 1 ))
INSERT INTO SPRAVOTDEL VALUES ( 111 ,	"Терапия",	 1 )
INSERT INTO SPRAVOTDEL VALUES ( 112 ,	"Хирургия",	 2 )
INSERT INTO SPRAVOTDEL VALUES ( 242 ,	"Неврология",	 3 )
INSERT INTO SPRAVOTDEL VALUES ( 252 ,	"Урология",	 4 )
INSERT INTO SPRAVOTDEL VALUES ( 262 ,	"Педиатрия",	 5 )
INSERT INTO SPRAVOTDEL VALUES ( 282 ,	"Кардиология",	 6 )

SET ENGINEBEHAVIOR  70 
SELECT MAX(b.datarecord) as datarecord, b.cd, b.sostvse from spravotdel as a, motion as b ;
		WHERE BETWEEN(a.sortnum, 2 , 5 ) AND b.cd=a.keymine INTO CURSOR result GROUP BY  2 
SELECT result
BROWSE

Ну что это сложно было самому сделать ?
...
Рейтинг: 0 / 0
09.03.2010, 15:15
    #36509131
Ewgeny911
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать с таблицы записи по последней дате
Вообще-то уже три недели голову ломаю. Написал вопрос потому что уже устал от поисков, ничего придумать не получается.
thunder2 - Ваш запрос тоже не получается запустить. Не работает. Подозреваю что стандарный BDE не понимает некоторых выражений. Вот этих:
Код: plaintext
1.
2.
3.
4.
SET ENGINEBEHAVIOR  70 
INTO CURSOR
BROWSE
BETWEEN(a.sortnum, 2 , 5 )
Вот эту строку проглатывает нормально (но конечно без точки запятой в конце):
Код: plaintext
SELECT MAX(b.datarecord) as datarecord, b.cd, b.sostvse from spravotdel as a, motion as b
GROUP BY тоже понимает, но только без двойки в конце - там требует имя поля.
Вообщем вот это работает:
Код: plaintext
1.
SELECT  Max(M.DATERECORD), S.KEYMINE from "MOTION.DBF" M LEFT OUTER JOIN "SPRAVOTDEL.DBF" S ON S.KEYMINE = M.CD GROUP BY S.KEYMINE
Но этого недостаточно, точнее это почти ничего не даёт. Нужно чтобы в таблице было ещё одно поле из таблицы "MOTION.DBF"- ключевое "KEY1", чтобы можно было однозначно определить запись Но как его вставить в этот запрос? Вообще всего в "MOTION.DBF" около 30 полей.
Если никак выбрать записи SQL запросом не удастся, придётся циклом по таблице, но это наихудший вариант, не хотелось бы...
...
Рейтинг: 0 / 0
09.03.2010, 16:06
    #36509303
eeerrt
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать с таблицы записи по последней дате
Код: plaintext
1.
2.
3.
SELECT MAX(b.datarecord) as dtrecmax, b.cd, b.sostvse; 
from spravotdel a, motion b;
wHERE a.sortnum between  2  and  5  AND b.cd=a.keymine;
group by b.cd,b.sostave
...
Рейтинг: 0 / 0
09.03.2010, 20:31
    #36510015
Ewgeny911
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать с таблицы записи по последней дате
eeerrt - Cпасибо за ответ! Ваш запрос выполняется без ошибок, но результат не тот.
Выдаются все записи из таблицы MOTION, ведь группировка идёт по двум поля.
Т.е. в результирующую таблицу попадают нескользо записей с отделением 111, несколько с 112 и т.д. А нужно то только по одной записи каждого отделения, но последней по дате.
Код, который я приводил:
Код: plaintext
SELECT  Max(M.DATERECORD), S.KEYMINE from "MOTION.DBF" M LEFT OUTER JOIN "SPRAVOTDEL.DBF" S ON S.KEYMINE = M.CD GROUP BY S.KEYMINE
Результат:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
MAX OF DATERECORD	KEYMINE
 24 . 01 . 2010 	 111 
 24 . 01 . 2010 	 112 
 24 . 01 . 2010 	 114 
 24 . 01 . 2010 	 115 
 24 . 01 . 2010 	 221 
 24 . 01 . 2010 	 222 
 24 . 01 . 2010 	 331 
 24 . 01 . 2010 	 332 
 24 . 01 . 2010 	 333 
 24 . 01 . 2010 	 334 
....
...
Перечисляются все отделения по одному разу. Это то, что нужно, за единственным исключением - нет поля SOSTVSE, которое в MOTION. (Или вместо SOSTVSE можно было бы взять ключевое автоинкрементное поле KEY1 которое также в MOTION - это без разницы) Вообщем вопрос только в том, как добавить ещё одну колонку в этот запрос. И эта колонка должна быть из MOTION. Насчёт того чтобы брать из справочника SPRAVOTDEL не все отделения, а только некоторые (...BETWEEN...) - это ладно и без этого можно обойтись. Хотя это нужно, но и без этого сойдёт. Попробую ещё раз пояснить что нужно. Нужно получить список записей из таблицы MOTION последних по дате по каждому отделению. Справочник SPRAVOTDEL в принципе вообще в запросе не нужен. Нужны только записи из MOTION и всё. SPRAVOTDEL нужен только для указания дипазона кодов отделений, а если без диапазона, так наверное и без SPRAVOTDEL можно обойтись. Получается нужно выбрать из таблицы MOTION все встречающиеся коды отделений (по одному разу (... может как то с помощью DISTINCT ?) и найти для каждого отделения последнюю по дате запись. Это упрощённый вариант того, что я первоначально написал в вопросе. И этого будет достаточно.
...
Рейтинг: 0 / 0
09.03.2010, 23:57
    #36510298
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать с таблицы записи по последней дате
Выбрать из дочерней таблицы записи с максимальной датой

Поскольку Вы работаете через BDE, то, скорее всего, это означает аналог ODBC-драйвера для FoxPro. Т.е. Вам нужно решение для версии VFP6, поскольку драйверов ODBC для старших версий не выпускалось. Для VFP9 был выпущен драйвер OLE DB (ADO).
...
Рейтинг: 0 / 0
10.03.2010, 09:42
    #36510660
eeerrt
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать с таблицы записи по последней дате
Ewgeny911Нужно получить список записей из таблицы MOTION последних по дате по каждому отделению. SPRAVOTDEL нужен только для указания дипазона кодов отделений.
Код: plaintext
1.
2.
3.
SELECT MAX(b.datarecord) as dtrecmax, b.cd,COUNT(distinct b.sostvse)kol_sostv, MIN(b.sostvse)minsostv,MAX(b.sostvse)maxsostv; 
from spravotdel a, motion b;
wHERE a.sortnum between  2  and  5  AND b.cd=a.keymine;
group by b.cd
...
Рейтинг: 0 / 0
10.03.2010, 23:02
    #36512859
Ewgeny911
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать с таблицы записи по последней дате
eeerrt Спасибо за ответ! Запрос выполяется без ошибок, но опять результат не тот.
В запросе стоят COUNT(distinct b.sostvse) kol_sostv, MIN(b.sostvse)minsostv,MAX(b.sostvse)maxsostv
Но ведь не нужно какие то расчётные данные по полю sostvse. Нужно само значение поля sostvse в конкретной записи в MOTION - той записи которая была добавлена последней по дате для соотвтствующего отделения (поле CD). Фактически нужно не какие то расчётные значения получить, а список записей из MOTION, по одной для каждого значения в поле CD, но введённой последней по дате. Поле CD - код отделения, их всего уникальных около 60, они повтояются для каждой даты. Но если б они повторялись все без исключения, то можно было бы отсортировать таблицу по дате и взять все записи по последней дате. Проблема в том что не все они повторяются в каждой введённой дате...

Можно бы и все поля из MOTION взять ... типа SELECT * FROM MOTION WHERE... вот только что после WHERE?) а к таблице SPRAVOTDEL можно и не обращаться - если она камень приткновения.
...
Рейтинг: 0 / 0
11.03.2010, 10:16
    #36513223
eeerrt
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать с таблицы записи по последней дате
Ewgeny911 eeerrt Спасибо за ответ! Запрос выполяется без ошибок, но опять результат не тот.
а к таблице SPRAVOTDEL можно и не обращаться - если она камень приткновения.
Нет камень преткновения-нежелание автора думать собственной головой. Вас подтолкнули к решению:может быть дальше стоит попробовать самому разобраться:позапросить к базе и так и эдак,выкинуть ненужные поля,подкорректировать условие(если нужно) и т.д. ?
...
Рейтинг: 0 / 0
11.03.2010, 19:16
    #36515051
Ewgeny911
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать с таблицы записи по последней дате
Причём тут нежелание? Вероятно это вообще нвозможно. Уже три недели каждый день пытаюсь найти хоть какое то решение. Ладно... нет, так нет. Если б это срочно нужно было - давно бы уже сделал циклом, но это как то неправильно. Готов заплатить за решение... Если оно конечно вообще существует. А пока сделаю через цикл.
...
Рейтинг: 0 / 0
11.03.2010, 19:19
    #36515055
Ewgeny911
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать с таблицы записи по последней дате
Причём тут нежелание? Вероятно это вообще нвозможно. Уже три недели каждый день пытаюсь найти хоть какое то решение. Ладно... нет, так нет. Если б это срочно нужно было - давно бы уже сделал циклом, но это как то неправильно. Готов заплатить за решение... Если оно конечно вообще существует. А пока сделаю через цикл.
...
Рейтинг: 0 / 0
11.03.2010, 20:19
    #36515172
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать с таблицы записи по последней дате
Ewgeny911Причём тут нежелание? Вероятно это вообще нвозможно. Уже три недели каждый день пытаюсь найти хоть какое то решение. Ладно... нет, так нет. Если б это срочно нужно было - давно бы уже сделал циклом, но это как то неправильно. Готов заплатить за решение... Если оно конечно вообще существует. А пока сделаю через цикл.
Это именно не желание. Я дал Вам ссылку на решение. Вероятно, Вы вообще туда не сходили.

На всякий случай намекну. Подчеркнутая строка - это ссылка. Надо навести на нее указатель мыши и шелкнуть левой клавишей мыши

Выбрать из дочерней таблицы записи с максимальной датой

Вот Вам адаптированный вариант решения описанного по ссылке в случае, если для одного CD не может быть несколько записей с одинаковой (максимальной) датой

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
SELECT tabMain.*, tab2.* ;  
FROM SPRAVOTDEL tabMain;  
INNER JOIN MOTION tab2 ON tabMain.KEYMINE = tab2.CD ;  
WHERE tabMain.SORTNUM BETWEEN  2  AND  5  ;
	AND NOT EXISTS(SELECT 'x' FROM MOTION ;  
			WHERE tab2.CD = MOTION.CD ;  
				AND tab2.DATERECORD < MOTION.DATERECORD) ;


Про общий случай, надеюсь, все-таки почитаете по ссылке...
...
Рейтинг: 0 / 0
18.03.2010, 08:38
    #36527421
Ewgeny911
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать с таблицы записи по последней дате
Вообщем так и не получилось...
ВладимирМ Спасибо за помощь. Этот запрос тоже не срабатывает, хотя и компилируется без ошибок. Выполняется и программа зависает, только по диспечеру видно как кушает память...
Насчёт того примера... тема похожая, но разобраться не получилось. Попробовал подойти к проблеме с другой стороны, сделал без SQL запроса, через цикл. Сейчас всё работает, по скорости тоже норм. Так что вопрос снят. Хотя если б всё таки через SQL решение было бы красивее.
...
Рейтинг: 0 / 0
18.03.2010, 11:13
    #36527770
Zmej
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать с таблицы записи по последней дате
Этот запрос тоже не срабатывает
вот как раз запрос Максимова работает нормально. Но все равно получить результирующие данные так как Вам хотелось не получится. Ведь Вы скромно умолчали, а что делать если для одного отделения (код 112) есть две записи с максимальной датой? А то что запрос не отрабатывает в BDE - то ищите проблемы в BDE. Могу предложить еще свой вариант:
Код: plaintext
1.
2.
3.
4.
5.
SELECT tabMain.*, tab2.* ;  
FROM SPRAVOTDEL tabMain;  
INNER JOIN MOTION tab2 ON tabMain.KEYMINE = tab2.CD ;  
WHERE tabMain.SORTNUM BETWEEN  2  AND  5  ;
	AND daterecord = (Select MAX(daterecord) as daterecord FROM motion WHERE motion.CD = tabMain.KEYMINE)
но он тоже не решает проблему повторов
...
Рейтинг: 0 / 0
18.03.2010, 11:15
    #36527781
Zmej
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать с таблицы записи по последней дате
Этот запрос тоже не срабатывает
вот как раз запрос Максимова работает нормально. Но все равно получить результирующие данные так как Вам хотелось не получится. Ведь Вы скромно умолчали, а что делать если для одного отделения (код 112) есть две записи с максимальной датой? А то что запрос не отрабатывает в BDE - то ищите проблемы в BDE. Могу предложить еще свой вариант:
Код: plaintext
1.
2.
3.
4.
5.
SELECT tabMain.*, tab2.* ;  
FROM SPRAVOTDEL tabMain;  
INNER JOIN MOTION tab2 ON tabMain.KEYMINE = tab2.CD ;  
WHERE tabMain.SORTNUM BETWEEN  2  AND  5  ;
	AND daterecord = (Select MAX(daterecord) as daterecord FROM motion WHERE motion.CD = tabMain.KEYMINE)
но он тоже не решает проблему повторов
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
15.05.2012, 09:06
    #37794177
1clinux
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать с таблицы записи по последней дате
Max Using the OVER clause will help YOU!
...
Рейтинг: 0 / 0
15.05.2012, 09:12
    #37794181
1clinux
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать с таблицы записи по последней дате
...
Рейтинг: 0 / 0
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Выбрать с таблицы записи по последней дате / 17 сообщений из 17, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]