Конференция "Базы" » select from select в FireBird 2.0.1/2.1 [D7, FireBird 2.x]
 
  • Виталий Панасенко(дом) (14.04.08 13:58) [0]
    Здравствуйте. Такой вот вопрос возник.Есть запрос
    SELECT
    A.NUM,
    IIF(D.DOC_STATUS IS NULL, 0, D.DOC_STATUS) AS DOC_STATUS,
    D.PERIOD_BEG,
    D.period_end,
    P.PLAST_ID,
    P.PLAST_NAME,
    D.SUMMA,
    C.CLIENT_ID,
    (select MONTHSBETWEEN from
    SP_MONTHSBETWEEN(:P1, :P2))AS MONTHBETWEEN,
    (select MONTHSBETWEEN*IIF(D.SUMMA IS NULL, 0, D.SUMMA) from
    SP_MONTHSBETWEEN(:P1, :P2))AS FULLSUMMA
    FROM
     ADDRESS A
    LEFT JOIN DOC D
      ON(A.NUM=D.NUM_ID)
    LEFT JOIN STATUS S
      ON(S.STATUS_ID=D.DOC_STATUS)
    LEFT JOIN CLIENTS C
       ON (D.CLIENT_ID=C.CLIENT_ID)
    LEFT JOIN  PLAST_TYPE P
       ON(P.PLAST_ID=A.PLAST_ID)
    WHERE (D.PERIOD_BEG <= :P2) AND
         (D.PERIOD_END >= :P1) or ((D.doc_status = 0) or (d.doc_status is null))

    Период - это строка в виде ГГГГММ. Работает он так, как мне нужно. Но мне вдобавок еще нужно эти данные потом сгруппировать (но не всегда, зависит от выбора оператора) по PLAST_ID и/или CLIENT_ID... Думаю "сделаю я выборку из выборки"... в итоге получаем не верный результат. поле FULLSUMMA = первой записи из приведенного запроса... при попытке сгруппировать
    select doc_status,  count(doc_status) as cnt, sum(fullsumma) as fullsumma from(
    SELECT
    количество подсчитывается правильно, а вот сумма!..там фантастические результаты. Заворачиваю подзапрос в ХП, выполняю - результат такой, какой и ожидался, правильный... SP_MONTHSBETWEEN - ХП расчитывает кол-во месяцев между начальным и конечным периодом...
    Я то хранимку сделал..Но интересно - почему без нее получаю неверный результат(проверить просто - из 1313 записей, только у 3 есть и должно быть значение в поле FULLSUMMA, сложить смог.:-) )
  • Johnmen © (14.04.08 14:54) [1]
    Можно глянуть на процедуру получения разницы дат в месяцах?
  • Виталий Панасенко(дом) (14.04.08 16:18) [2]
    SET TERM ^ ;

    CREATE OR ALTER PROCEDURE SP_MONTHSBETWEEN (
       period varchar(6),
       period2 varchar(6))
    returns (
       monthsbetween smallint)
    as
    declare variable d date;
    declare variable sd varchar(10);
    declare variable i smallint;
    begin
     /* Procedure Text */
    D = cast(substring(:PERIOD from 1 for 4)||'-'||substring(:PERIOD from 5 for 2)||'-'||'28' as date);
    I = 0;
    while (SUBSTRING(CAST(:D AS varchar (10)) FROM 1 FOR 4)||SUBSTRING(CAST(:D AS varchar(10)) from 6 for 2)<=:PERIOD2) do
     begin
        SD = cast(:D as varchar(10));
        D = cast(substring(:SD from 1 for 4)||'-'||substring(:SD from 6 for 2)||'-'||'28' as date);
        D = :D+4;
        I = :I+1;
     end
     monthsbetween = :I;
     suspend;
    end^

    SET TERM ; ^
  • Johnmen © (14.04.08 16:50) [3]
    Прочёл внимательней [0].
    Чтобы получить разницу в месяцах УДФ не нужна. Просто используй EXTRACT(MONTH ...
  • Johnmen © (14.04.08 16:55) [4]
    Т.е. ХП не нужна... :))
  • Виталий Панасенко(дом) (14.04.08 19:07) [5]

    > Johnmen ©   (14.04.08 16:50) [3]
    >
    > Прочёл внимательней [0].
    > Чтобы получить разницу в месяцах УДФ не нужна. Просто используй
    > EXTRACT(MONTH ...

    это я не понял... насчет извлечения месяца(EXTRACT(MONTH...))... дата нигде не мелькает(в данном случае).. да и ответ не в тему: почему select from select выдает неправильный результат... глюк ПрицЫ ?  или мой ? я со своей строно не заметил...и конструкцию select from (select) воспринимаю буквально: внутренний select - это таблица для внешнего.. оказалось, не совсем
  • Виталий Панасенко(дом) (14.04.08 19:08) [6]

    > Johnmen ©   (14.04.08 16:55) [4]
    >
    > Т.е. ХП не нужна... :))
    >

    а разница ?
  • Johnmen © (14.04.08 19:27) [7]

    > Виталий Панасенко(дом)   (14.04.08 19:07) [5]
    > это я не понял... насчет извлечения месяца(EXTRACT(MONTH...))... дата
    > нигде не мелькает(в данном случае)..

    Так пусть мелькает. Притом это проще, чем мелькать 'ГГГГММ'

    >  да и ответ не в тему

    Ну если тебе это не интересно, то мне и подавно.

    > почему select from select выдает неправильный результат...

    Должен заметить, что ты нигде не привел этого. И над чем мы должны думать?
  • Виталий Панасенко(дом) (14.04.08 19:31) [8]
    а если тему и первый пост мой перечитать?
    > select from select в FireBird 2.0.1/2.1 [D7, FireBird 2.
    > x]


    > Думаю "сделаю я выборку из выборки"
  • Johnmen © (14.04.08 19:35) [9]
    Ну так приведи, как сделал-то. Не заставляй напрягаться наши изношенные телепаторы :)
  • Виталий Панасенко(дом) (14.04.08 20:55) [10]
    вроде привел....

    > select doc_status,  count(doc_status) as cnt, sum(fullsumma)
    > as fullsumma from(
    > SELECT количество подсчитывается правильно, а вот сумма!
    >
    </
    далее

    > SELECT
    > A.NUM,
    > IIF(D.DOC_STATUS IS NULL, 0, D.DOC_STATUS) AS DOC_STATUS,
    >
    > D.PERIOD_BEG,
    > D.period_end,
    > P.PLAST_ID,
    > P.PLAST_NAME,
    > D.SUMMA,
    > C.CLIENT_ID,
    > (select MONTHSBETWEEN from
    > SP_MONTHSBETWEEN(:P1, :P2))AS MONTHBETWEEN,
    > (select MONTHSBETWEEN*IIF(D.SUMMA IS NULL, 0, D.SUMMA) from
    > SP_MONTHSBETWEEN(:P1, :P2))AS FULLSUMMA
    > FROM
    >  ADDRESS A
    > LEFT JOIN DOC D
    >   ON(A.NUM=D.NUM_ID)
    > LEFT JOIN STATUS S
    >   ON(S.STATUS_ID=D.DOC_STATUS)
    > LEFT JOIN CLIENTS C
    >    ON (D.CLIENT_ID=C.CLIENT_ID)
    > LEFT JOIN  PLAST_TYPE P
    >    ON(P.PLAST_ID=A.PLAST_ID)
    > WHERE (D.PERIOD_BEG <= :P2) AND
    >      (D.PERIOD_END >= :P1) or ((D.doc_status = 0) or (d.
    > doc_status is null))
    >

    то же из первого поста...
  • Johnmen © (14.04.08 21:29) [11]
    А как с помощью ХП? Доловно.
  • Виталий Панасенко(дом) (14.04.08 21:35) [12]

    > Johnmen ©   (14.04.08 21:29) [11]
    >
    > А как с помощью ХП? Доловно.

    Дословно?
    select doc_status, sum(fullsumma) as fullsumma, count(doc_status) as cnt
    from sp_statistic(:p1, :p2)
    group by doc_status
    работает.. и отбирает то что нужно.. я чего тему затронул: я не знаю, я "гоню" или сервер.. но если сервер, то м.б. разработчики обратят внимание на такую ситуацию.. а если я... то нафиг...:-)
  • Johnmen © (14.04.08 22:33) [13]
    Ещё - откуда берется :p1 и :p2 в случае запроса из запроса?
  • Виталий Панасенко(дом) (14.04.08 22:43) [14]

    > Johnmen ©   (14.04.08 22:33) [13]

    это параметры: начальный и конечный период
  • Johnmen © (14.04.08 22:51) [15]

    > Виталий Панасенко(дом)   (14.04.08 22:43) [14]

    Для эксперимента попробуй явно задать значения.
  • Виталий Панасенко(дом) (15.04.08 09:55) [16]

    > Johnmen ©   (14.04.08 22:51) [15]
    >
    >
    > > Виталий Панасенко(дом)   (14.04.08 22:43) [14]
    >
    > Для эксперимента попробуй явно задать значения.
    >

    Не помогло
  • Johnmen © (15.04.08 10:32) [17]

    > Виталий Панасенко(дом)   (15.04.08 09:55) [16]
    > Не помогло

    Все-таки приведи конкретный код, как с явным заданием значений.
  • Виталий Панасенко(дом) (15.04.08 12:08) [18]
    Ха! Когда убрал ХП из запроса - заработало!
    select doc_status,  count(doc_status) as cnt, sum(fullsumma) as fullsumma from(
    SELECT
    A.NUM,
    IIF(D.DOC_STATUS IS NULL, 0, D.DOC_STATUS) AS DOC_STATUS,
    D.PERIOD_BEG,
    D.period_end,
    P.PLAST_ID,
    P.PLAST_NAME,
    D.SUMMA,
    1 AS MONTHBETWEEN, --- ТУТ БЫЛ ВЫЗОВ ХП
    1*IIF(D.SUMMA IS NULL, 0, D.SUMMA) AS FULLSUMMA --- И ТУТ
    FROM
     ADDRESS A
    LEFT JOIN DOC D
      ON(A.NUM=D.NUM_ID)
    LEFT JOIN STATUS S
      ON(S.STATUS_ID=D.DOC_STATUS)
    LEFT JOIN CLIENTS C
       ON (D.CLIENT_ID=C.CLIENT_ID)
    LEFT JOIN  PLAST_TYPE P
       ON(P.PLAST_ID=A.PLAST_ID)
    WHERE ((D.PERIOD_BEG <= '200801') AND
         (D.PERIOD_END >= '200801')) or ((D.doc_status = 0) or (d.doc_status is null)))
    group by 1

  • Johnmen © (15.04.08 12:34) [19]

    > Виталий Панасенко(дом)   (15.04.08 12:08) [18]

    1. С ХП с явными значениями работает?
    2. Для получения разницы в месяцах никакая ХП не нужна - я уже говорил [3]
 
Конференция "Базы" » select from select в FireBird 2.0.1/2.1 [D7, FireBird 2.x]
Есть новые Нет новых   [134432   +19][b:0][p:0.001]