Погода: -12°C
  • Тут у знакомого возник один вопрос по delphi + Interbase, я, к сожалению в этом профан, поэтому решил тут спросить.

    Допустим, есть две таблицы:

    таблица ордеров (Ordera)
    I_Ord - код ордера
    Dat - дата
    VdOr - 'P' - приходный ордер, 'R' - расходный ордер

    таблица товаров (Tovars)
    I_Tov - код товара
    I_Ord - код ордера
    Kvo - количество

    Одной записи в Ordera может соответствовать несколько в Tovars (связь по I_Ord). Задача получить остаток товара.

    Следующий запрос дает список всего товара, причем кол-во товара по приходным ордерам идет со знаком '+', а по расходным ордерам -со знаком '-':

    SELECT OD.I_TOV, TV.KVOT
    FROM PRORDS OD, PRTOVS TV
    WHERE OD.I_OR=TV.I_OR AND OD.VDOR="P"
    UNION
    SELECT OD.I_TOV, -1*TV.KVOT
    FROM PRORDS OD, PRTOVS TV, MATCEN MC
    WHERE OD.I_OR=TV.I_OR AND OD.VDOR="R"

    Теперь хорошо бы просуммировать эти данные, сгруппировав по коду товара (I_Tov), но как обратиться к результату этого запроса в Delphi?

    Должно быть что-то типа:
    SELECT I_Tov, SUM(KvoT) AS KvoT
    FROM
    GROUP BY I_Tov

    Может можно получить результат одним SQL-запросом?

    Или есть какой-нибудь другой вариант?

  • разве не проще сделать ещё один запрос?

  • В смысле? А где промежуточные значения хранить?

  • 1. всё же лучше union all, имхо
    2. декартово произведение не есть хорошо
    3.1 результаты запроса сохраняются в файл, после чего запросом обращаемся к этому файлу.
    3.2 мысли вслух: а не проще ли значения хранить со знаками и колонку с признаком убрать

  • Не знаю как другие, а я бы не парясь создал просмотр по результату первого запроса и второй запрос делал по просмотру

    Скромность украшает мужчину. Но настоящий мужчина в украшениях не нуждается.

  • Дело в том, что это оказалось тествое задание и комментарии по нормализации таблицы не принимаются:улыб:А вообще говоря я ему нашёл такое решение, если кому интересно - Замена временных таблиц в FireBird

    По-моему довольно стильно и всё по-честному без всяких дополнительных файлов:улыб:

  • Схематично:
    я бы добавил таблицу такого вида
    CREATE TABLE DocTypes
    (
    DocTypeID char(1)not null primary key,
    Multiplier integer not null
    )
    и занес туда 2 записи: ('P',1) и ('R',-1)

    Тогда запрос легко переписывается к такому виду

    SELECT OD.I_TOV, SUM(TV.KVOT*DT.Multiplier)
    FROM
    PRORDS OD
    INNER JOIN PRTOVS TV ON OD.I_OR=TV.I_OR
    INNER JOIN DocTypes DT ON OD.VDOR=DT.DocTypeID

    без всяких UNION'ов, вьюшек(UNION в них недопустим) и лишних наворотов.

    P.S. Не забудьте добавить FK по полю DocTypeID:улыб:

    P.P.S. Писать запросы с условием объединения в WHERE, а не на JOIN'ах - очень дурной тон, если это делается не на Оракле.

    P.P.P.S. Даже если это тестовое задание, то не улучшить структуру в данном случае- это еще более дурной тон.

    who | grep -i blonde | date; cd ~; unzip; touch;
    strip; finger; mount; gasp; yes; uptime; umount;

  • Спасибо. передам:улыб:

Записей на странице:

Перейти в форум

Модератор: