Конференция "Базы" » Выбор записей, в которой значение поля становится отрицательным
 
  • Не местный (18.01.13 13:07) [0]
    Сервер DB2. Есть таблица:
    ID1(int, PK), ID2(int, PK), OPERATION(строка), REST(int)

    ID1 - это ссылка на другую таблицу. Таких ссылок может быть несколько, поэтому введено поле ID2 (фактически, ID2 - это порядковые номера записей с одинаковым ID1).

    OPERATION - строковый код операции. Нужно выбрать записи по критерию
    (OPERATION = 'ВЫДАЧА' and REST < 0)


    - но не все, а только те, для которых REST в записи с тем же ID1 и с предыдущим ID2 неотрицательный.

    Например из таблицы:

    ID1   ID2   OPERATION   REST
    1      1      что-то         5
    1      2      ВЫДАЧА       3
    1      3      ВЫДАЧА      -1
    1      4      что-то        -1
    2      1      что-то         10
    2      2      что-то         0
    2      3      ВЫДАЧА      -7
    2      4      что-то         -20


    надо выбрать строки:

    1      3      ВЫДАЧА      -1
    2      3      ВЫДАЧА      -7


    Не могу сообразить, как это сделать. Памажите пажалуста, сами мы не местные...
  • Ega23 © (18.01.13 13:27) [1]
    ID2 в строгом порядке идёт, или разрывы могут быть?
  • Не местный (18.01.13 13:37) [2]
    ID2 без разрывов.

    Вот что сочинил - вроде, работает, но очень прошу покритиковать. Кроме правильности интересует еще и скорость (таблица содержит десятки миллионов записей).

    select t1.*
    from
     (select * from ТАБЛИЦА where rest < 0 and operation = 'ВЫДАЧА') as t1,
     ТАБЛИЦА as t2
    where
     t2.id1 = t1.id1 and t2.id2 = (t1.id2 - 1) and t2.rest >= 0
    order by
     t1.id1

  • Не местный (18.01.13 13:41) [3]

    > ID2 без разрывов.

    Но строки в таблице никак не упорядочены.
  • Ega23 © (18.01.13 14:31) [4]
    select t1.id1, t1.id2, t1.operation, t1.rest
    from ttt t1
     join ttt t2 on (t1.id1 = t2.id1) and (t2.id2 = t1.id2-1)
    where t1.operation= 'тру-ля-ля' and t1.rest < 0
    order by t1.id1



    Как-от так, вроде. Скорость - фиг знает, смотреть надо.
    Я бы посоветовал Operation заменить на OperationID, два инта сравнить не медленнее, чем 2 строки.
  • Romkin © (18.01.13 14:59) [5]

    > select t1.id1, t1.id2, t1.operation, t1.restfrom ttt t1
    >   join ttt t2 on (t1.id1 = t2.id1) and (t2.id2 = t1.id2-
    > 1)where t1.operation= 'тру-ля-ля' and t1.rest < 0order by
    > t1.id1


    только в join надо бы добавить условие (t2.REST > 0)
  • Romkin © (18.01.13 15:01) [6]
    тьфу, t2.REST >= 0 конечно (предыдущий остаток неотрицателен).
  • Ega23 © (18.01.13 15:04) [7]

    > только в join надо бы добавить условие (t2.REST > 0)

    А есть разница?
    Вроде, от СУБД зависит.
  • Не местный (18.01.13 17:15) [8]
    Фуф. Полный запрос сработал секунд за 30 (все, что было выше - это всего лишь один из подзапросов, а в полном запросе идет связка еще по двум таблицам, и каждая - тоже на десятки миллионов). Не так уж плохо.

    Всем спасибо.
  • Кщд (20.01.13 21:20) [9]
    >Не местный   (18.01.13 17:15) [8]
    Нет ничего хорошего в двух проходах по таблице.
    СУБД какая?
  • Ega23 © (21.01.13 15:15) [10]

    > СУБД какая?

    DB2, в [0] же написано
  • Кщд (22.01.13 07:31) [11]
    >Ega23 ©   (21.01.13 15:15) [10]
    действительно, не заметил
    так в DB2 же есть аналитика, которая позволяет получить искомое без самообъединения
 
Конференция "Базы" » Выбор записей, в которой значение поля становится отрицательным
Есть новые Нет новых   [134430   +1][b:0][p:0.002]