powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Помогите с запросом, PLEASE
16 сообщений из 16, страница 1 из 1
Помогите с запросом, PLEASE
    #39381308
Цветовод
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Firebird v 2.5.

Есть таблица:
Код: sql
1.
2.
3.
4.
5.
6.
CREATE TABLE VAL_INT (
    ID       INTEGER NOT NULL,
    TAG      VARCHAR(10),
    VDATA    DATE,
    VTIME    TIME,
    VAL      INTEGER);


ID TAG VDATA VTIME VAL1 B 09.01.2017 06:00 02 A 09.01.2017 09:34 3333 A 09.01.2017 12:56 4444 A 09.01.2017 15:30 5555 B 09.01.2017 18:00 16 A 09.01.2017 19:15 07 A 10.01.2017 01:25 7778 A 10.01.2017 03:45 8889 A 10.01.2017 05:43 99910 B 10.01.2017 06:00 011 A 10.01.2017 07:21 111112 A 10.01.2017 08:17 2222
Мне надо:
1. Выбрать все значения для тэга A за период с 09.01.2017 по 10.01.2017
в обратном порядке по хронологии
2. Для каждого тэга A выбрать последнее предшествующее по времени
значение тэга B

12 A 10.01.2017 08:17 2222 10 B 10.01.2017 6:00 011 A 10.01.2017 07:21 1111 10 B 10.01.2017 6:00 0 9 A 10.01.2017 05:43 999 5 B 09.01.2017 18:00 1 8 A 10.01.2017 03:45 888 5 B 09.01.2017 18:00 1 7 A 10.01.2017 01:25 777 5 B 09.01.2017 18:00 1 6 A 09.01.2017 19:15 0 5 B 09.01.2017 18:00 1 4 A 09.01.2017 15:30 555 1 B 09.01.2017 6:00 0 3 A 09.01.2017 12:56 444 1 B 09.01.2017 6:00 0 2 A 09.01.2017 09:34 333 1 B 09.01.2017 6:00 0
Первое просто:

Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT V.ID, V.TAG, V.VDATA, V.VTIME, V.VAL
  FROM VAL_INT V
  WHERE 
      (V.TAG = :T) 
    AND
      (V.VDATA BETWEEN :B AND :E)
  ORDER BY V.VDATA DESC, V.VTIME DESC


А вот второе никак не получается.
Запросом вообще что-то даже мыслей нет, как сделать,
а в процедуре если пишу

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
...
  for SELECT V.ID, V.TAG, V.VDATA, V.VTIME, V.VAL
        FROM VAL_INT V
        WHERE ((V.TAG = :T) AND (V.VDATA BETWEEN :B AND :E))
        ORDER BY V.VDATA DESC, V.VTIME DESC
  into :ID, :TAG, :VDATA, :VTIME, :VAL
  do
  begin
    SELECT FIRST 1 B.VDATA, B.VTIME, B.VAL
      FROM VAL_INT B
      WHERE ((B.TAG = :R) AND ((B.VDATA <= :VDATA) AND (B.VTIME <= :VTIME)))
      ORDER BY B.VTIME DESC
    into :RDATA, :RTIME, :REFVAL;
    suspend;
    end
  end
...


получатся неправильно: ищется тэг "B", у которого И дата, И время меньше, чем у тэга "А".
То есть для тэгов "A" с ID 7, 8 и 9 тэг "B" найден не будет.
В общем, не выходить каменный цветок.

Подскажите, пожалуйста, куда грести?
...
Рейтинг: 0 / 0
Помогите с запросом, PLEASE
    #39381320
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Цветовод,

Код: sql
1.
WHERE B.TAG = :R AND (B.VDATA <= :VDATA OR B.VDATA = :VDATA AND B.VTIME <= :VTIME)
...
Рейтинг: 0 / 0
Помогите с запросом, PLEASE
    #39381323
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Цветовод,

1. Надо было делать поле с типом timestamp а не разбивать на дату и время
2. В 3.0 см. функцию LAG
3. в 2.5 как-то так

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
  RDATA = NULL;
  RTIME = NULL;
  REFVAL = NULL;
  for SELECT V.ID, V.TAG, V.VDATA, V.VTIME, V.VAL
        FROM VAL_INT V
        WHERE ((V.TAG = :T) AND (V.VDATA BETWEEN :B AND :E))
        ORDER BY V.VDATA DESC, V.VTIME DESC
  into :ID, :TAG, :VDATA, :VTIME, :VAL
  do
  begin
    suspend;
    RDATA = VDATA;
    RTIME  = VTIME;
    REFVAL = VAL;
  end
...
Рейтинг: 0 / 0
Помогите с запросом, PLEASE
    #39381328
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

а у тебя там ещё и разбиение по tag есть
...
Рейтинг: 0 / 0
Помогите с запросом, PLEASE
    #39381333
Цветовод
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
WildSery,
Неа, я так тоже пробовал. Не цветок.
...
Рейтинг: 0 / 0
Помогите с запросом, PLEASE
    #39381336
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Цветовод,

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
...
  for SELECT V.ID, V.TAG, V.VDATA, V.VTIME, V.VAL
        FROM VAL_INT V
        WHERE ((V.TAG = :T) AND (V.VDATA BETWEEN :B AND :E))
        ORDER BY V.VDATA + V.VTIME DESC
  into :ID, :TAG, :VDATA, :VTIME, :VAL
  do
  begin
    SELECT FIRST 1 B.VDATA, B.VTIME, B.VAL
      FROM VAL_INT B
      WHERE (B.TAG = :R) AND (V.VDATA + V.VTIME <= :VDATA + :VTIME)
      ORDER BY V.VDATA + V.VTIME DESC
    into :RDATA, :RTIME, :REFVAL;
    suspend;
    end
  end
...



производительность будет ниже плинтуса. Пока не поздно добавь поле timestamp. Запрос сильно упроститься
...
Рейтинг: 0 / 0
Помогите с запросом, PLEASE
    #39381337
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Цветовод,

Шарик, ты балбес (ц)

Неужели сам не видишь?
В одном месте написал ORDER BY V.VDATA DESC, V.VTIME DESC, а в другом, почему-то ORDER BY B.VTIME DESC
...
Рейтинг: 0 / 0
Помогите с запросом, PLEASE
    #39381339
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Цветовод,
FB правильно понимает вот такой синтаксис:
Код: sql
1.
((B.VDATA + B.VTIME) <= (:VDATA + :VTIME))


Попробуйте.
...
Рейтинг: 0 / 0
Помогите с запросом, PLEASE
    #39381948
Цветовод
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
WildSeryШарик, ты балбес (ц)
За Шарика ответишь! )))
WildSeryВ одном месте написал ORDER BY V.VDATA DESC, V.VTIME DESC, а в другом, почему-то ORDER BY B.VTIME DESC
Не, не айс. Так всегда выбирается тэг с ID = 10, т.е. всегда срабатывает вторая часть WHERE (которая после OR).
...
Рейтинг: 0 / 0
Помогите с запросом, PLEASE
    #39381949
Цветовод
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денис
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
...
  for SELECT V.ID, V.TAG, V.VDATA, V.VTIME, V.VAL
        FROM VAL_INT V
        WHERE ((V.TAG = :T) AND (V.VDATA BETWEEN :B AND :E))
        ORDER BY V.VDATA + V.VTIME DESC
  into :ID, :TAG, :VDATA, :VTIME, :VAL
  do
  begin
    SELECT FIRST 1 B.VDATA, B.VTIME, B.VAL
      FROM VAL_INT B
      WHERE (B.TAG = :R) AND (V.VDATA + V.VTIME <= :VDATA + :VTIME)
      ORDER BY V.VDATA + V.VTIME DESC
    into :RDATA, :RTIME, :REFVAL;
    suspend;
    end
  end
...

А вот это работает.
Симонов Дениспроизводительность будет ниже плинтуса.Не, не ниже. Она ваще никакая.)) Но это понятно.
Симонов ДенисПока не поздно добавь поле timestamp. Запрос сильно упроститьсяЯ не могу изменять типы полей. В базу пишет другая программа. Не моя. Это сервис сбора данных с оборудования. Без исходников.
Но я могу для себя добавить такое поле и формировать его триггером.
Я, конечно, протестирую такой вариант.
...
Рейтинг: 0 / 0
Помогите с запросом, PLEASE
    #39381950
Цветовод
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
KreatorXXI, Денис обогнал тебя, но все равно спасибо.
...
Рейтинг: 0 / 0
Помогите с запросом, PLEASE
    #39381951
Цветовод
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Тут у меня возникла мысль - развернуть порядок выборки в процедуре - сначала дернуть все тэги "B",
а потом для каждого из них делать выборку "A".
Пойду-ка я эту мысль думать.
...
Рейтинг: 0 / 0
Помогите с запросом, PLEASE
    #39382029
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЦветоводНе, не айс. Так всегда выбирается тэг с ID = 10, т.е. всегда срабатывает вторая часть WHERE (которая после OR)."Вы что, за меня и есть будете?! - Ага!" (ц)
Написать "<" для вместо "<=" попробуй.
Мне показалось очевидным, что при сравнении на равенство в качестве предыдущей сама себя всегда выбирать будет.
...
Рейтинг: 0 / 0
Помогите с запросом, PLEASE
    #39382065
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Дениспроизводительность будет ниже плинтуса. Пока не поздно добавь поле timestampИли индекс по выражению, убывающий
...
Рейтинг: 0 / 0
Помогите с запросом, PLEASE
    #39382238
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЦветоводKreatorXXI, Денис обогнал тебя, но все равно спасибо.
Не заметил. Сорри. Ну, акцентировал внимание на фиче, будем считать.
...
Рейтинг: 0 / 0
Помогите с запросом, PLEASE
    #39382832
Цветовод
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hvladИли индекс по выражению, убывающийДелал VDATA + VTIME. Производительность растет, несущественно (где-то в 2,5 раза)

KreatorXXIНе заметил. Сорри. Ну, акцентировал внимание на фиче, будем считать. OK.

ЦветоводТут у меня возникла мысль - развернуть порядок выборки в процедуре - сначала дернуть все тэги "B",
а потом для каждого из них делать выборку "A".
Пойду-ка я эту мысль думать. Короче.
- Добавил поле TIMESTAMP (формируется в триггере BEFORE INSERT)
- Сделал по нему DESC индекс.
- в процедуре поменял порядок - см. выше.
Результат великолепный - все просто летает. Спасибо всем!
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Помогите с запросом, PLEASE
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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