Конференция "Базы" » Как составить запрос к базе [D7, FB 2]
 
  • OtherSie (23.04.09 22:29) [0]
    Есть 2 таблицы. 1-я - справочник. Содержит в себе список работников и первичный ключ. Вторая - список заказов с прикреплёнными к ним работниками. Содержит 4 поля - внешние ключи - ссылки на первичный ключ первой таблицы и 5-е поле - первичный ключ заказов.

    Нужно выбрать фамилии из первой таблицы по запросу нужного значения первичного ключа во второй таблице.

    Как сделать с хранимой процедурой с четырьмя подзапросами - знаю.

    Можно ли как-то выполнить задачу одним запросом? Спасибо.
  • sniknik © (23.04.09 23:06) [1]
    > Как сделать с хранимой процедурой с четырьмя подзапросами - знаю.
    процедура и 4-ре подзапроса для объединения 2-х таблиц? мощно! внишаит!...

    хочу знать способ. заинтриговал чертяка. а то одним запросом это как то банально и мелко...
  • turbouser © (23.04.09 23:13) [2]

    > sniknik ©   (23.04.09 23:06) [1]

    А то!  Хочу энто видеть !
  • AndreyV © (23.04.09 23:25) [3]
    > [1] sniknik ©   (23.04.09 23:06)
    > хочу знать способ. заинтриговал чертяка. а то одним запросом
    > это как то банально и мелко...

    Бартер?
  • OtherSie (23.04.09 23:45) [4]
    Как-то так:



    create procedure NEW_PROCEDURE (
       TEST_UID integer)
    returns (
       FIO1 char(10),
       FIO2 char(10),
       FIO3 char(10),
       FIO4 char(10))
    as
    begin
     select VOC_CONTANT
     from VOCAB, TEST
     where TEST.TEST_UID = :TEST_UID and
           VOCAB.VOC_UID = TEST.TEST1
     into :FIO1;
     select VOC_CONTANT
     from VOCAB, TEST
     where TEST.TEST_UID = :TEST_UID and
           VOCAB.VOC_UID = TEST.TEST2
     into :FIO2;
     select VOC_CONTANT
     from VOCAB, TEST
     where TEST.TEST_UID = :TEST_UID and
           VOCAB.VOC_UID = TEST.TEST3
     into :FIO3;
     select VOC_CONTANT
     from VOCAB, TEST
     where TEST.TEST_UID = :TEST_UID and
           VOCAB.VOC_UID = TEST.TEST4
     into :FIO4;
     suspend;
    end

    select * from NEW_PROCEDURE(1)




    Возвращает то, что мне нужно.
  • OtherSie (23.04.09 23:47) [5]
    Можно ли как-то компактнее сделать?
  • sniknik © (24.04.09 00:23) [6]
    т.е. тебе нужно вот это
    select VOC_CONTANT
    from VOCAB, TEST
    where TEST.TEST_UID = 1 and
            (VOCAB.VOC_UID = TEST.TEST1 or
             VOCAB.VOC_UID = TEST.TEST2 or
             VOCAB.VOC_UID = TEST.TEST3 or
             VOCAB.VOC_UID = TEST.TEST4)
    должен выдать список из 4х полей.
  • sniknik © (24.04.09 00:28) [7]
    но вообще, так не делается, соединяют обычно по одному полю, потому как располагают данные в "высоту" таблицы, а не "ширину" тогда и количество этих данных не будет ограничено 4-мя... да и работать удобнее.
  • OtherSie (24.04.09 00:50) [8]

    > т.е. тебе нужно вот это select VOC_CONTANT



    > должен выдать список из 4х полей.


    Запрос выдаст только одно поле. И 4 условия лишние.


    > но вообще, так не делается, соединяют обычно по одному полю, потому как располагают данные в "высоту" таблицы, а не "ширину" тогда и количество этих данных не будет ограничено 4-мя... да и работать удобнее.


    Если бы удалось выполнить задачу одним запросом - можно было бы отдавать в качестве результата множество записей. Сейчас BETWEEN никак не напишешь, конечно.

    Как вообще делается я знаю. Можно было бы предложить сделать четыре справочника вместо одного. Тогда, конечно, никаких проблем бы не было. Но, дело в том, что одни и те же люди могут входить в разные справочники одновременно (поля TEST1 - TEST4 - это, как я поняли из задания, специальности, необходимые для выполнения задания. они у разных людей могут пересекаться). Поэтому добавление еще трёх справочников приведёт к явной денормальзации базы.
  • OtherSie (24.04.09 00:52) [9]

    > апрос выдаст только одно поле. И 4 условия лишние.


    Сорри, проглючило :)  or не увидел. Буду тестить. Возможно - самое то...
  • Игорь Шевченко © (24.04.09 00:54) [10]

    > (поля TEST1 - TEST4 - это, как я поняли из задания, специальности,
    >  необходимые для выполнения задания. они у разных людей
    > могут пересекаться).


    такой глупый вопрос - а если для выполнения задания потребуется, не дай Аллах, пять специальностей ?

    Вроде как примеров с Job и Skill в любом учебнике по SQL навалом - бери да переписывай любой.
  • OtherSie (24.04.09 00:56) [11]
    Ыыыы.... Не то. Таки да - вернулось же много записей с одним полем. И Between-то работает, но не так, как нужно. ХП то как раз возвращает одну запись с четырьмя полями... Но - слишком сложно и только для одного uid'а...
  • OtherSie (24.04.09 01:02) [12]

    > такой глупый вопрос - а если для выполнения задания потребуется,
    >  не дай Аллах, пять специальностей ?


    Ну и хорошо - добавят еще одно поле (допустим - TEST5), в джобы - нужных людей, у которых есть нужный скилл.


    > Вроде как примеров с Job и Skill в любом учебнике по SQL
    > навалом - бери да переписывай любой.


    Порылся - сходу не нашел. Самому как-то такие задачи не попадались ранее.
  • OtherSie (24.04.09 01:43) [13]
    Нашел таки :)


     select TABL1.VOC_CONTANT, TABL2.VOC_CONTANT, TABL3.VOC_CONTANT, TABL4.VOC_CONTANT
     from VOCAB TABL1, VOCAB TABL2, VOCAB TABL3, VOCAB TABL4, TEST
     where TEST.TEST_UID between 1 and 2 and
           TABL1.VOC_UID = TEST.TEST1 and
           TABL2.VOC_UID = TEST.TEST2 and
           TABL3.VOC_UID = TEST.TEST3 and
           TABL4.VOC_UID = TEST.TEST4




    Не видел раньше алиасов у таблиц :)
  • sniknik © (24.04.09 01:56) [14]
    > Ну и хорошо - добавят еще одно поле (допустим - TEST5), в джобы - нужных людей, у которых есть нужный скилл.
    может сразу тогда этим людям дать программу писать? которые будут твое творение править. у них наверняка лучше получится (лень заставит. как пару раз что нибудь вылезет на поправку когда уже все, что делалось забыл, так сразу научатся головой работать а не руками).

    > Порылся - сходу не нашел. Самому как-то такие задачи не попадались ранее.
    вообще то их полно. но они на непонятной для тебя, правильной, классической логике. которую ты не воспринимаешь.

    например простая накладная - справочник товаров + справочник документов, отбрасываем разные отвлекающие поля вроде типа накладной, цен товаров для записей, и т.д. оставляем только названия товаров и id для связей как у тебя.
    остается - поле  с номером накладной, и поле связи по id со справочником товаров. в "высоту" прошу заметить, никому в голову не приходит для каждой накладной, полей в "ширину" добавлять, если вдруг товаров больше пришло. и все. по этим двум полям все находится, все записи накладной, по ее номеру, все названия товаров из присоединенного по полю связи справочника. и все в "высоту". так удобнее.
    не, конечно и там среди бухгалтеров попадаются отщепенцы, придумали такую вещь как шахматка... но и ее делают. чаще всего "поворачивая"  полученный результат на клиенте, делая из "высоты" "ширину". можно и на сервере, легко могу сделать на access или mssql  но на FB боюсь их синтаксис не пройдет, даже не пытаться не стоит (а трудов чтобы разбираться задача не стоит. глупая логика).
  • Германн © (24.04.09 02:04) [15]

    > sniknik ©   (24.04.09 01:56) [14]

    Количество двойных кавычек превысило все разумные пределы.
    :)
  • sniknik © (24.04.09 02:06) [16]
    > Нашел таки :)
    даже не написал на нашел? докатились.

    тогда понятно почему запрос "кривоват" - по логике данного запроса данные во всех  полях связей обязательны, к тому же по строгому соответствию, получается можно объединить народ по четверкам и оставить одно поле... будет то же самое.
  • OtherSie (24.04.09 02:56) [17]

    > например простая накладная - справочник товаров + справочник
    > документов, отбрасываем разные отвлекающие поля вроде типа
    > накладной, цен товаров для записей, и т.д. оставляем только
    > названия товаров и id для связей как у тебя.остается - поле
    >  с номером накладной, и поле связи по id со справочником
    > товаров. в "высоту" прошу заметить, никому в голову не приходит
    > для каждой накладной, полей в "ширину" добавлять, если вдруг
    > товаров больше пришло. и все. по этим двум полям все находится,
    >  все записи накладной, по ее номеру, все названия товаров
    > из присоединенного по полю связи справочника. и все в "высоту".
    >  так удобнее.не, конечно и там среди бухгалтеров попадаются
    > отщепенцы, придумали такую вещь как шахматка... но и ее
    > делают. чаще всего "поворачивая"  полученный результат на
    > клиенте, делая из "высоты" "ширину". можно и на сервере,
    >  легко могу сделать на access или mssql  но на FB боюсь
    > их синтаксис не пройдет, даже не пытаться не стоит (а трудов
    > чтобы разбираться задача не стоит. глупая логика).


    Что то ты в дебри полез. Было достаточно сказать, что у таблиц могут быть псевдонимы.


    > даже не написал на нашел?


    Не уверен, что верно понял сказанное. Имелось в виду, что нашел, что у таблиц могут быть алиасы. Хорошая фича.


    > данные во всех  полях связей обязательны,


    Без проблем. Делаем дефолтное значение 0 у таблицы джобов, а нулевому юиду ставим в соответствие что-нибудь типа 'не назначено'.
  • AndreyV © (24.04.09 07:47) [18]
    > [17] OtherSie   (24.04.09 02:56)
    > Что то ты в дебри полез. Было достаточно сказать, что у
    > таблиц могут быть псевдонимы.

    И это всё, что ты увидел в ответе, хотя об этом в нём не говорилось.

    Экселем мыслим.
  • MsGuns © (24.04.09 09:15) [19]
    >Имелось в виду, что нашел, что у таблиц могут быть алиасы. Хорошая фича.

    Как много нам открытий чудных
    Готовит просвещенья дух
    И опыт, сын ошибок трудных,
    И гений, парадоксов друг
     :))
 
Конференция "Базы" » Как составить запрос к базе [D7, FB 2]
Есть новые Нет новых   [134473   +32][b:0][p:0.001]