Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / выборка последнего движения / 25 сообщений из 31, страница 1 из 2
29.12.2008, 11:18
    #35739319
АлексейО
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
Есть 2 таблицы справочник сотрудников K1 и движения сотрудников K2, хочется получить список сотрудников с данними только последнего движения.
собственно в фоксе я бы назначить отношение по обратному индексу даты движения и scan по справочнику - набрал бы нужные данные.
однако хочется сделать select-sql
казалось бы:
Код: plaintext
1.
SELECT k2_temp.postn, fam,im, otch, k2_temp.cex, k2_temp.tabn  FROM k1 ;
INNER JOIN (SELECT cex, tabn FROM k2 TOP  1  ORDER BY dper DESC) as k2_temp ON k2_temp.postn = k1.postn
ан нет - говорит синтаксическая ошибка.
подскажите пожалуйста как бы сделать такую выборку?
...
Рейтинг: 0 / 0
29.12.2008, 11:29
    #35739349
выборка последнего движения
АлексейОЕсть 2 таблицы справочник сотрудников K1 и движения сотрудников K2, хочется получить список сотрудников с данними только последнего движения.
собственно в фоксе я бы назначить отношение по обратному индексу даты движения и scan по справочнику - набрал бы нужные данные.
однако хочется сделать select-sql
казалось бы:
Код: plaintext
1.
SELECT k2_temp.postn, fam,im, otch, k2_temp.cex, k2_temp.tabn  FROM k1 ;
INNER JOIN (SELECT cex, tabn FROM k2 TOP  1  ORDER BY dper DESC) as k2_temp ON k2_temp.postn = k1.postn
ан нет - говорит синтаксическая ошибка.
подскажите пожалуйста как бы сделать такую выборку?
Top обычно идет сразу за словом select, а не где-то там в конце запроса.
...
Рейтинг: 0 / 0
29.12.2008, 11:32
    #35739354
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
АлексейОЕсть 2 таблицы справочник сотрудников K1 и движения сотрудников K2, хочется получить список сотрудников с данними только последнего движения.
собственно в фоксе я бы назначить отношение по обратному индексу даты движения и scan по справочнику - набрал бы нужные данные.
однако хочется сделать select-sql
казалось бы:
Код: plaintext
1.
SELECT k2_temp.postn, fam,im, otch, k2_temp.cex, k2_temp.tabn  FROM k1 ;
INNER JOIN (SELECT cex, tabn FROM k2 TOP  1  ORDER BY dper DESC) as k2_temp ON k2_temp.postn = k1.postn
ан нет - говорит синтаксическая ошибка.
подскажите пожалуйста как бы сделать такую выборку?
А где вы такой синтаксис про TOP нашли?
Может так:
Код: plaintext
1.
SELECT k2_temp.postn, fam,im, otch, k2_temp.cex, k2_temp.tabn  FROM k1 ;
INNER JOIN (SELECT TOP  1  cex, tabn FROM k2 ORDER BY dper DESC) as k2_temp ON k2_temp.postn = k1.postn
С уважением, Алексей
...
Рейтинг: 0 / 0
29.12.2008, 11:32
    #35739355
АлексейО
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
проходящий.Top обычно идет сразу за словом select, а не где-то там в конце запроса. перестановка не помогла - ошибка таже
...
Рейтинг: 0 / 0
29.12.2008, 11:36
    #35739362
АлексейО
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
select в скобках отдельно исполняется удачно и с нужними данными
Код: plaintext
SELECT TOP  1  cex, tabn FROM k2 ORDER BY dper DESC WHERE k2.postn = k1.postn
...
Рейтинг: 0 / 0
29.12.2008, 11:36
    #35739363
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
АлексейОпроходящий.Top обычно идет сразу за словом select, а не где-то там в конце запроса. перестановка не помогла - ошибка таже
У вас в подзапросе нет поля postn, а вы его перечисляете как результат!
Код: plaintext
1.
2.
SELECT k2_temp.postn, fam,im, otch, k2_temp.cex, k2_temp.tabn  FROM k1 ;
INNER JOIN (SELECT TOP  1  cex, tabn, postn FROM k2 ORDER BY dper DESC) as k2_temp ON k2_temp.postn = k1.postn
С уважением, Алексей.
...
Рейтинг: 0 / 0
29.12.2008, 11:37
    #35739368
АлексейО
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
Aleksey-K,
ну не помогает эта перестановка
...
Рейтинг: 0 / 0
29.12.2008, 11:41
    #35739381
АлексейО
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
Aleksey-KУ вас в подзапросе нет поля postn, а вы его перечисляете как результат!
Код: plaintext
1.
2.
SELECT k2_temp.postn, fam,im, otch, k2_temp.cex, k2_temp.tabn  FROM k1 ;
INNER JOIN (SELECT TOP  1  cex, tabn, postn FROM k2 ORDER BY dper DESC) as k2_temp ON k2_temp.postn = k1.postn

поправил - syntax error.
...
Рейтинг: 0 / 0
29.12.2008, 11:42
    #35739384
АлексейО
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
добавлю что VFP 8 , полагаю что не принципиально.
...
Рейтинг: 0 / 0
29.12.2008, 11:42
    #35739385
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
АлексейО, а версия VFP у вас какая ?
...
Рейтинг: 0 / 0
29.12.2008, 11:44
    #35739392
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
АлексейОдобавлю что VFP 8 , полагаю что не принципиально.
Ничего себе не принципиально!
Только в VFP 9.0 появились TOP n в корреляционных подзапросах:
Вот цитата из HELP

Что нового в SELECT-SQL VFP 9.0:

TOP N in a Non-Correlated Subquery
Visual FoxPro 9.0 supports the TOP N clause in a non-correlated subquery. The ORDER BY clause should be present if the TOP N clause is used, and this is the only case where it is allowed in subquery.

The following is the general syntax for the TOP N clause in a non-correlated subquery.

SELECT … WHERE … (SELECT TOP nExpr [PERCENT] … FROM … ORDER BY …) …

С уважением, Алексей
...
Рейтинг: 0 / 0
29.12.2008, 11:49
    #35739401
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
Поправляю себя - в некорреляционных подзапросах.
Как раз ваш случай.
Переходите на VFP 9.0 или через временный курсор.
С уважением, Алексей
...
Рейтинг: 0 / 0
29.12.2008, 12:20
    #35739466
АлексейО
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
Aleksey-K,
Да . действительно. в 9ке синтакс прошел. однако получил не ту информацию что ожидал - разбираюсь...
...
Рейтинг: 0 / 0
29.12.2008, 12:51
    #35739554
АлексейО
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
АлексейО,

получается что подзапрос выполняется 1 раз а не на каждой иттерации основного запроса как ожидал я.
...
Рейтинг: 0 / 0
29.12.2008, 12:54
    #35739566
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
АлексейОAleksey-K,
Да . действительно. в 9ке синтакс прошел. однако получил не ту информацию что ожидал - разбираюсь...
И не должны были получить :)
Внутренний запрос выбирает TOP 1 из всех postn!
Может так получится:
Код: plaintext
1.
2.
3.
4.
SELECT k1.postn, k1.fam, k1.im,  k1.otch, k2_temp.cex, k2_temp.tabn  ;
FROM k1 INNER JOIN (SELECT k2.postn, k2.cex, k2.tabn FROM k2 ;
WHERE k2.dper = (SELECT MAX(kx.dper) FROM k2 kx ON k2.postn = kx.postn)) ;
AS k2_temp ON k2_temp.postn = k1.postn
С уважением, Алексей
...
Рейтинг: 0 / 0
29.12.2008, 12:58
    #35739579
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
АлексейОАлексейО,

получается что подзапрос выполняется 1 раз а не на каждой иттерации основного запроса как ожидал я.
Тогда вам нужен внутренний корреляционный подзапрос.
А он с TOP n и в VFP 9.0 не работает.
С уважением, Алексей
...
Рейтинг: 0 / 0
29.12.2008, 13:27
    #35739675
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
Вместо решения "в лоб" через TOP 1 надо просто объединить таблицы и добавить исключение записей с датой, для которых существует бОльшая дата

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SELECT 
    k2.postn, ;
    k1.fam, ;
    k1.im, ;
    k1.otch, ;
    k2.cex, ;
    k2.tabn  ;
FROM k1 ;
INNER JOIN k2 ON k2.postn = k1.postn ;
WHERE NOT EXISTS(select 'x' from k2 as k2_exist ;
                            where k2_exist.postn = k2.postn and k2_exist.dper > k2.dper)

Разумеется, это имеет смысл, если нет дублей по дате. Точнее, нет двух записей с максимальной датой.

Правда, не уверен, что такой запрос синтаксически корректен для VFP8.
...
Рейтинг: 0 / 0
29.12.2008, 13:29
    #35739681
АлексейО
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
Aleksey-KМожет так получится:
Код: plaintext
1.
2.
3.
4.
SELECT k1.postn, k1.fam, k1.im,  k1.otch, k2_temp.cex, k2_temp.tabn  ;
FROM k1 INNER JOIN (SELECT k2.postn, k2.cex, k2.tabn FROM k2 ;
WHERE k2.dper = (SELECT MAX(kx.dper) FROM k2 kx ON k2.postn = kx.postn)) ;
AS k2_temp ON k2_temp.postn = k1.postn

да. цель достигнута.
но впрочем я ей достигал за 2 select-a и за меньшее время.
я то надеялся что написав в одном я сокращю время.
и практически уверен что scan выполнит это еще быстрее
...
Рейтинг: 0 / 0
29.12.2008, 13:35
    #35739700
АлексейО
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
ВладимирМВместо решения "в лоб" через TOP 1 надо просто объединить таблицы и добавить исключение записей с датой, для которых существует бОльшая дата
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SELECT 
    k2.postn, ;
    k1.fam, ;
    k1.im, ;
    k1.otch, ;
    k2.cex, ;
    k2.tabn  ;
FROM k1 ;
INNER JOIN k2 ON k2.postn = k1.postn ;
WHERE NOT EXISTS(select 'x' from k2 as k2_exist ;
                            where k2_exist.postn = k2.postn and k2_exist.dper > k2.dper)

да. спасибо. это тоже работает, но практически за такое же время.
...
Рейтинг: 0 / 0
29.12.2008, 13:35
    #35739701
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
АлексейОAleksey-KМожет так получится:
Код: plaintext
1.
2.
3.
4.
SELECT k1.postn, k1.fam, k1.im,  k1.otch, k2_temp.cex, k2_temp.tabn  ;
FROM k1 INNER JOIN (SELECT k2.postn, k2.cex, k2.tabn FROM k2 ;
WHERE k2.dper = (SELECT MAX(kx.dper) FROM k2 kx ON k2.postn = kx.postn)) ;
AS k2_temp ON k2_temp.postn = k1.postn

да. цель достигнута.
но впрочем я ей достигал за 2 select-a и за меньшее время.
я то надеялся что написав в одном я сокращю время.
и практически уверен что scan выполнит это еще быстрее
Все зависит от наличия подходящих индексов. Например, по postn во всех таблицах и по dper в k2
С уважением, Алексей
...
Рейтинг: 0 / 0
29.12.2008, 13:39
    #35739715
АлексейО
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
Aleksey-KВсе зависит от наличия подходящих индексов. Например, по postn во всех таблицах и по dper в k2 да. эти индексы есть и 40 т. записей обрабатывает за 13-14 секунд, но этого мне мало.
...
Рейтинг: 0 / 0
29.12.2008, 13:51
    #35739750
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
АлексейОAleksey-KВсе зависит от наличия подходящих индексов. Например, по postn во всех таблицах и по dper в k2 да. эти индексы есть и 40 т. записей обрабатывает за 13-14 секунд, но этого мне мало.
Для отчета - вполне нормальное время. Пользователь воспримет такую задержку при выполнении отчета с пониманием и не будет "дергаться".

А для текущей работы нет смысла отбирать 40 тысяч записей. Ни один пользователь не в состоянии "охватить" такой объем информации. Т.е. отбираемую информацию надо ограничить какими-либо дополнительными условиями. Например, движения сотрудников за последний месяц.
...
Рейтинг: 0 / 0
29.12.2008, 14:01
    #35739774
АлексейО
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
ВладимирМ,
да мне надо для оперативной работы и я могбы отобрать по условию первой таблицы, но это дает сокращение только на десятые, а фильтры по второй таблице невозможны (вдруг там нет движений за последний месяц, а сведения нужны)
впрочем, всем СПАСИБО. а получил ответ.
...
Рейтинг: 0 / 0
29.12.2008, 14:12
    #35739809
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
АлексейО, Все понятно...
Но если движения может и не быть, я бы переделал INNER JOIN на LEFT JOIN и заменил бы k2_temp.cex и k2_temp.tabn на NVL(k2_temp.cex, 0) AS cex и NVL(k2_temp.tabn, 0) AS tabn соответственно (если они цифровые, иначе на пустую строку). Итого:
Код: plaintext
1.
2.
3.
4.
SELECT k1.postn, k1.fam, k1.im,  k1.otch, NVL(k2_temp.cex,  0 )  AS cex, NVL(k2_temp.tabn,  0 ) AS tabn ;
FROM k1 LEFT JOIN (SELECT k2.postn, k2.cex, k2.tabn FROM k2 ;
WHERE k2.dper = (SELECT MAX(kx.dper) FROM k2 kx ON k2.postn = kx.postn)) ;
AS k2_temp ON k2_temp.postn = k1.postn
Но все-таки оставил бы SELECT-SQL, а не SCAN...ENDSCAN
Вдруг, будете перводить свое приложение на клиент-сервер. Проще будет эту операцию выполнить, если как можно больше в ANSI-SQL.
С уважением, Алексей
...
Рейтинг: 0 / 0
29.12.2008, 14:18
    #35739822
АлексейО
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
выборка последнего движения
Aleksey-KНо если движения может и не быть, хоть одно движение есть, просто неизвестно когда оно, может человек устроился на завод 20 лет назад и простоял перед одним станком
Aleksey-KВдруг, будете перводить свое приложение на клиент-сервер. Проще будет эту операцию выполнить, если как можно больше в ANSI-SQL.
именно так я и рассуждал, но ... 4 секунды против 13-ти ... я выбрал scan.
СПАСИБО за помощь.
...
Рейтинг: 0 / 0
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / выборка последнего движения / 25 сообщений из 31, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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