powered by simpleCommunicator - 2.0.55     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Помогите с представлением
17 сообщений из 17, страница 1 из 1
Помогите с представлением
    #36584178
tansoc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Неиндексированный файл отсортирован по дате DATE и времени TIME.
Записи содержат случайные по времени измерения величины Y.

Хочу получить представление, в котором все было бы ужато до:
1. дата
2. значение Y на начало дня
3. значение Y на конец дня
4. максимальное значение Y в течение дня


Сделал GROUP BY date.
Для пункта 4: MAX(Y)

А, пункты 2 и 3 стали камнем преткновения.

Мне нужно написать собственную функцию для представления ?
Или можно обойтись стандартными?
...
Рейтинг: 0 / 0
Помогите с представлением
    #36584204
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tansoc,

Фокса под рукой нет, но вопрос показался интересным, поэтому приведу пример решения с использованием стандартного SQL на Oracle, думаю без труда сможете перенести на FoxPro.
Есть одно но - данный пример работает при условии уникальности поля tm. Если оно неуникально - доработаете напильником.
Имеем входные данные:
Входные данные
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
with s as
(select trunc(date '2010-01-01') +  10  as dt,  2  as y, date '2010-01-01' +  10 . 10  as tm from dual union all
 select trunc(date '2010-01-01') +  10  as dt,  3  as y, date '2010-01-01' +  10 . 20  as tm from dual union all
 select trunc(date '2010-01-01') +  10  as dt,  1  as y, date '2010-01-01' +  10 . 30  as tm from dual union all
 select trunc(date '2010-01-03') +  20  as dt,  4  as y, date '2010-01-01' +  20 . 10  as tm from dual union all
 select trunc(date '2010-01-03') +  20  as dt,  5  as y, date '2010-01-01' +  20 . 20  as tm from dual union all
 select trunc(date '2010-01-03') +  20  as dt,  6  as y, date '2010-01-01' +  20 . 30  as tm from dual
)

dt y tm11.01.2010 2 11.01.2010 2:24:0011.01.2010 3 11.01.2010 4:48:0011.01.2010 1 11.01.2010 7:12:0023.01.2010 4 21.01.2010 2:24:0023.01.2010 5 21.01.2010 4:48:0023.01.2010 6 21.01.2010 7:12:00
Запрос, вытягивающий необходимые данные
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
select s1.dt, s2.y as y_begin, s3.y as y_end, s1.y as y_max 
from
   (select s1.dt, max(s1.y) y, min(tm) tm1, max(tm) tm2
    from s s1
    group by s1.dt
   ) s1
   left join s s2 on s1.dt = s2.dt and s1.tm1 = s2.tm
   left join s s3 on s1.dt = s3.dt and s1.tm2 = s3.tm
Результат
dt y_begin y_end y_max11.01.2010 2 1 323.01.2010 4 6 6

Если интересно - пример решения на Oracle с использованием аналитических ф-ий
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select dt, y_begin, y_end, y_max
from
   (select s.dt, 
    first_value(y) over (partition by dt order by tm asc ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) y_begin,
    last_value(y)  over (partition by dt order by tm asc ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) y_end,
    max(y)         over (partition by dt) y_max,
    row_number()   over (partition by dt order by tm) rn
    from s
   )
where rn =  1     
...
Рейтинг: 0 / 0
Помогите с представлением
    #36584376
igorbik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tansoc,

Отлично. Все работает.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
select s1.dt, s2.y as y_begin, s3.y as y_end, s1.y as y_max ;
from ;
   (select s1.dt, max(s1.y) y, min(tm) tm1, max(tm) tm2 ;
    from s ;
    group by s1.dt ;
   ) s1 ;
   left join s s2 on s1.dt = s2.dt and s1.tm1 = s2.tm ;
   left join s s3 on s1.dt = s3.dt and s1.tm2 = s3.tm 
...
Рейтинг: 0 / 0
Помогите с представлением
    #36587990
tansoc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо за внимание. Не помогло. Я сделал даже из вашего примера табличку, но ваш запрос в VPF-9 не захотел работать.
К тому же, у меня задачка немного сложнее. Думал, что справлюсь и упростил условие. А ума не хватило. :( Выглядеть должно так:

Во вложении есть dbf-файл mart c полями:
1. DATE
2. TIME
3. OPEN - цена на начало текущей минуты
4. CLOSE - цена на конец текущей минуты
5. LOW - минимум цены текущей минуты
6. HIGH -максимум текущей минуты

Время TIME меняется ежеминутно. Файл неиндексирован, но уже отсортирован по дате-времени. Нужен запрос для получения отчета по дням:

1. DATE
2. OPEN (значение из записи с минимальным временем на текущую DATE, собственно это первая запись на выбранную дату, т.к.файл сортирован)
3. HIGH (Значение с максимальным HIGH в течение дня)
4. LOW (значение с минимальным значением в течение дня)
5. CLOSE (значение из последней записи дня, т.е. с максимальным временем, ибо файл уже сортирован по дате времени

Собственно, тоже самое, только не в минутах, а в днях...


Мне тут дали пару вариантов, но они тоже в фоксе не работают:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Select Date, ;
  (Select Open From mart AS m1 Where m1.Date=mm.Date And m1.Time=(Select Min(Time) From mart AS m11 Where m11.Date=mm.Date)) AS Open, ;
   Max(High) AS High, ;
   Min(low) AS low, ;
  (Select Close From mart AS m2 Where m2.Date=mm.Date And m2.Time=(Select Max(Time) From mart AS m22 Where m22.Date=mm.Date)) AS Close ;
From mart AS mm

Select m1.Date, m2.Open, m1.High, m1.low, m3.Close ;
    from (Select Date, Min(Time) As mintime, Max(High) As High, Min(low) As low, Max(Time) As maxtime From mart Group By Date ) As m1 ;
  JOIN mart As m2 On m1.Date=m2.Date And m1.mintime=m2.Time ;
  JOIN mart As m3 On m1.Date=m3.Date And m1.maxtime=m3.Time

Первый вариант фоксу не нравится из-за сложности конструкции. А про второй пишет: "не символьным выражение"
...
Рейтинг: 0 / 0
Помогите с представлением
    #36588050
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tansoc,

А у тебя time случаем не как character хранится?
...
Рейтинг: 0 / 0
Помогите с представлением
    #36588065
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tansoc,

Если бы не OPEN и CLOSE, то можно было бы запросом, а так проще код написать.
Примерно так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
create Cursor tDay (dDate d, nOpen i, nHigh i, nLow i, nClose i)
sele mart
scan
	if tDay.dDate != mart.Date
		insert into tday (dDate, nOpen, nHigh, nLow, nClose) values (mart.Date, mart.Open, mart.High, mart.Low, mart.Close)
	else
		if tDay.nHigh < mart.High
			repl in tDay nHigh with mart.High
		endif
		if tDay.nLow > mart.Low
			repl in tDay nLow with mart.Low
		endif
		repl in tDay nClose with mart.Close
	endif
endscan
sele tDay
brow
...
Рейтинг: 0 / 0
Помогите с представлением
    #36588127
tansoc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AmKad,

TIME - character. А разве это может быть помехой? Точно также все сортируется. Точно такие же минимумы-максимумы

Вот, сейчас еще попробовал. Второй вариант выполнился. Действительно, выборка прошла.

Но при попытке сохранить не результаты, а сам запрос в файле пишет: not a character expression
...
Рейтинг: 0 / 0
Помогите с представлением
    #36588131
tansoc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima T, спасибо.

Но такой цикл я и сам мог бы написать. Мне хочется именно запросом. :)
...
Рейтинг: 0 / 0
Помогите с представлением
    #36588204
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tansocDima T, спасибо.

Но такой цикл я и сам мог бы написать. Мне хочется именно запросом. :)

Тогда сам голову ломай :) Зачем надо именно запросом? Ради спортивного интереса?

Проблемы возникают всегда когда в запросе с группировкой надо получить что-то из записи номер Х (первой, последней, предыдущей), а проблема эта от того что в SQL не понятия "номер записи", из-за этого приходится извращаться.
...
Рейтинг: 0 / 0
Помогите с представлением
    #36588268
tansoc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima T,

Меня уже поставили в известность, что в SQL нет понятия номер записи.

Проиндексировать файл проблем нет. А усливие min-max можно применять к символьному полю TIME.

Отчего запросом? Ну, пусть это моя прихоть. :)
Меня уже обрадовало, что второй запрос все таки ищет, что мне надо. Только почему-то не хочет в qpr-файл сохраняться. Я его пробую сделать через File-New-Query. Там открываю mart.dbf. А потом сразу пытаюсь вставить текст запроса в SQL-окно. Если я запускаю RUN, запрос срабатывает. Но если жму на дискетку, для сохранения qpr-файла, то сразу идет сообщение об ошибке. Может, чего не так делаю?

Не сохраняется сам текст запроса. И файл mart выбрасывает.
...
Рейтинг: 0 / 0
Помогите с представлением
    #36588280
tansocТолько почему-то не хочет в qpr-файл сохраняться. Я его пробую сделать через File-New-Query. Там открываю mart.dbf. А потом сразу пытаюсь вставить текст запроса в SQL-окно. Если я запускаю RUN, запрос срабатывает. Но если жму на дискетку, для сохранения qpr-файла, то сразу идет сообщение об ошибке. Может, чего не так делаю?Угую НЕ НАДО пользоваться посторителем запросов. Сделайте обычный текстовый файл, поместите туда запрос и сохраните с нужным расширением если уж оно Вам важно.

Не сохраняется сам текст запроса. И файл mart выбрасывает.Не умеет он с такими сложными запросами работать. Это костыль для полных чайников.
...
Рейтинг: 0 / 0
Помогите с представлением
    #36588313
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T а проблема эта от того что в SQL не понятия "номер записи", из-за этого приходится извращаться.
На всякий случай добавлю, что понятие "номер записи" наполняется смыслом лишь при задании способа сортировки. В данном случае у ТС-а порядок сортировки задается полем time.
...
Рейтинг: 0 / 0
Помогите с представлением
    #36588413
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Select ;
	t1.date, ;
	t2.open, ;
	(select Max(high) from mart t6 where t6.date = t1.date) as high, ;
	(select Min(low) from mart t7 where t7.date = t1.date) as low, ;
	t3.close ;
from mart as t1 ;
inner join mart as t2 on t1.date = t2.date ;
inner join mart as t3 on t1.date = t3.date ;
where not exists(select 'x' from mart t4 ;
			where t4.date = t2.date and t4.time < t2.time) ;
	and not exists(select 'x' from mart t5 ;
			where t5.date = t3.date and t5.time > t3.time) 
...
Рейтинг: 0 / 0
Помогите с представлением
    #36588463
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Извиняюсь, первая таблица в запросе лишняя

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Select ;
	t2.date, ;
	t2.open, ;
	(select Max(high) from mart t6 where t6.date = t2.date) as high, ;
	(select Min(low) from mart t7 where t7.date = t2.date) as low, ;
	t3.close ;
from mart as t2 ;
inner join mart as t3 on t2.date = t3.date ;
where not exists(select 'x' from mart t4 ;
			where t4.date = t2.date and t4.time < t2.time) ;
	and not exists(select 'x' from mart t5 ;
			where t5.date = t3.date and t5.time > t3.time)


И еще, приведенный запрос будет работать корректно только в случае, если нет однакового минимального или максимального time в течении дня. Если же есть дубли, то возникнут дубли записей в выборке. Впрочем, это можно решить через опцию DISTINCT
...
Рейтинг: 0 / 0
Помогите с представлением
    #36588466
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tansoc...
Мне тут дали пару вариантов, но они тоже в фоксе не работают:

Код: plaintext
1.
2.
3.
4.
...
Select m1.Date, m2.Open, m1.High, m1.low, m3.Close ;
    from (Select Date, Min(Time) As mintime, Max(High) As High, Min(low) As low, Max(Time) As maxtime From mart Group By Date ) As m1 ;
  JOIN mart As m2 On m1.Date=m2.Date And m1.mintime=m2.Time ;
  JOIN mart As m3 On m1.Date=m3.Date And m1.maxtime=m3.Time

Первый вариант фоксу не нравится из-за сложности конструкции. А про второй пишет: "не символьным выражение"
Этот вариант рабочий и наиболее быстрый по скорости из всех SELECT`ов, только будет задвоение если в исходных данных повторится запись с одинаковым первым(последним) датой-временем

AmKadDima T а проблема эта от того что в SQL не понятия "номер записи", из-за этого приходится извращаться.
На всякий случай добавлю, что понятие "номер записи" наполняется смыслом лишь при задании способа сортировки. В данном случае у ТС-а порядок сортировки задается полем time.
От того что оно смыслом наполнилось запрос проще не становится.

Все-таки в данной задаче SCAN предпочтительней, т.к. требуется гораздо меньше вычислений для получения результата.
...
Рейтинг: 0 / 0
Помогите с представлением
    #36588654
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
Все-таки в данной задаче SCAN предпочтительней, т.к. требуется гораздо меньше вычислений для получения результата.
Согласен, тот вариант, что я привел с аналитикой на Oracle работает также по приниципу одного СКАНА вместо трех - и оттого быстрее.
...
Рейтинг: 0 / 0
Помогите с представлением
    #36590871
A452
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
Согласен, тот вариант, что я привел с аналитикой на Oracle работает также по приниципу одного СКАНА вместо трех - и оттого быстрее.

Сдесь у нас форум по фоксе или "просто треп" ? :)


проходящий., ВладимирМ хватит их травмировать )
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Помогите с представлением
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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