Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2010.12.05;
Скачать: [xml.tar.bz2];

Вниз

применение full join   Найти похожие ветки 

 
_drug_   (2009-07-24 07:48) [0]

Есть две таблицы:
create table first_table (
 id integer not null,
 data1 somedatatype)

create table second_table(
 id integer not null,
 data2 somedatatype)

id есть PK в обоих таблицах, data1 и data2 собс-но данные. При этом записи с каким-либо id могут быть в first_table и отсутствовать в second_table и наоборот. Нужно объеденить эти таблицы по первичному ключу и я использовал full join:
select coalesce(f.id, s.id), f.data1, s.data2
 from first_table f full join second_table s on f.id = s.id

В целом, меня результат устраивает, но хотелось бы знать мнение более опытных товарищей о правильности использования full join"а в данном случае и вообще, а также есть ли ему альтернативы.
На подробностях не настаиваю, лаконичного ответа будет достаточно.


 
StriderMan   (2009-07-24 12:43) [1]

запрос сам себе противоречит:
...coalesce(f.id, s.id)

...on f.id = s.id

может нужен просто UNION
SELECT id, data from first_table
UNION
SELECT id, data from second_table

не?


 
topS   (2009-07-24 16:12) [2]

для соединения (а не объединения) таблиц существует JOIN, подробнейшим образом расписанный в любой даже самой примитивной документации

в чем проблема?


 
_drug_   (2009-07-24 18:08) [3]


> StriderMan   (24.07.09 12:43) [1]
> запрос сам себе противоречит:...coalesce(f.id, s.id)...on
> f.id = s.idможет нужен просто UNIONSELECT id, data from
> first_tableUNIONSELECT id, data from second_tableне?<Цит

Нет. Возможны случаи, когда либо f.id, либо s.id равен null, поэтому и заюзал full join. А data1 и data2 хранят разные данные.


 
_drug_   (2009-07-24 18:09) [4]


> topS   (24.07.09 16:12) [2]
> для соединения (а не объединения) таблиц существует JOIN,
>  подробнейшим образом расписанный в любой даже самой примитивной
> документациив чем проблема?

Меня интересует правильное решение я выбрал или есть более лучшие решения проблемы.


 
turbouser___   (2009-07-24 18:41) [5]


> _drug_   (24.07.09 18:09) [4]

Решение нормальное.


 
topS   (2009-07-24 19:22) [6]


> _drug_   (24.07.09 18:09) [4]
> более лучшие решения проблемы.

какой проблемы если не секрет?


 
Виталий Панасенко(дом)   (2009-07-25 10:40) [7]

а все-таки прикольно узнать, зачем все это?


 
_drug_   (2009-07-27 07:21) [8]


> topS
> какой проблемы если не секрет?

соединения таблиц


> Виталий Панасенко(дом)   (25.07.09 10:40) [7]
> а все-таки прикольно узнать, зачем все это?

Краткий экскурс в историю вопроса. Программирование мое хобби, последние 5 лет подзабросил. Теперь на работе по личной инициативе решил автоматизировать некоторые задачи, в ходе чего возникли вопросы, спросить не у кого, поэтому спрашиваю здесь. В частности про full join - мне показалось, что это слишком простое решение "в лоб", за простоту которого приходится платить нагрузкой на сервер и я решил это уточнить. Я ответил на вопрос?


 
Виталий Панасенко   (2009-07-27 09:37) [9]

Нет...имелось ввиду, что нужно получить.. я так и не понял. честно...


 
_drug_   (2009-07-27 11:36) [10]


> Виталий Панасенко  

Есть две таблицы, в одной фио и вес человека, в другой фио и его рост. причем для кого-то есть и рост и вес, для других что-то одно. нужно объеденить данные в одну таблицу, где и фио, и рост, и вес.
таблица рост:
фио       рост
вася      166
петя      180
коля      175

таблица вес:
фио       вес
ваня      55
вася      53
сережа  90

в итоге нужно получить:
фио      вес      рост
вася     53        166
ваня     55        null
петя     null       180
коля     null       175
сережа 90        null

inner join даст только
фио      вес      рост
вася     53        166

left и right join"ы тоже не то. остался full join, но большая нагрузка на сервер и я спросил здесь совета.


 
Anatoly Podgoretsky ©   (2009-07-27 11:48) [11]

> _drug_  (27.07.2009 11:36:10)  [10]

Неправильная структура, до нормализовались, 50 нормальной формы.


 
Виталий Панасенко   (2009-07-27 12:21) [12]

а на кой вес, характеризующий Васю лепить в от дельную таблицу?8-0. я б еще понял адрес, тогда для всех, проживающих по одному адресу указываем ИД адреса, а сам адрес - в отдельной(ых) таблице(ах)... а это - явный перебор...


 
_drug_   (2009-07-27 14:30) [13]


> Anatoly Podgoretsky

Анатолий, интуитивно догадываюсь, что вы хотели сказать, но толком не понял. :-)


> Виталий Панасенко  

а потому, что эти таблицы на самом деле view, в которых селектится куча таблиц, в силу нормализованности базы + некоторой неоптимальности структуры. и потом эти вьюхи объединяются в одну как раз по ФИО. единственно, что я смог улучшить, это за основу использовал таблицу со всеми ФИО, а потом левым джойном к ней прилепил эти вьюхи. не уверен, что комильфо, но это лучше. а если по уму, то надо переделать вьюхи, а это уже другая ветка будет, по-моему.
В общем, от full join"а я отказался, хотя вопрос остается, только по другому сформулирую - кто-то может привести пример, когда без full join не обойтись? или этот элемент SQL никогда не используется?


 
Anatoly Podgoretsky ©   (2009-07-27 14:59) [14]

> _drug_  (27.07.2009 14:30:13)  [13]

Еще раз, не надо отдельных таблиц, для однострочных данных, они должны составлять единое целое - Вася    53        166


 
Виталий Панасенко   (2009-07-27 16:32) [15]

вьюхи ж с таблиц созданы... почему вместо вьюх не использовать эти самые таблицы? правда, все структуры мы все равно не увидим..:-)


 
_drug_   (2009-07-28 08:11) [16]


> Виталий Панасенко  

Виталий, вот структура :-)

id, string50, string180, money, anumberof есть домены.

Дана таблица описывающая набор однотипных предметов.
CREATE TABLE TITEM (
 ITEM_ID INTEGER NOT NULL,
 MODEL STRING50,
 COMMENTS STRING180);


над каждым предметом может быть произведена одна или несколько процедур
CREATE TABLE TPROC_TYPE (
 ID ID NOT NULL,
 NAME STRING50 NOT NULL);


какая процедура над каким предметом проводятся и сколько она стоит хранится здесь (стоимость здесь, правда, избыточна, она считается на основе стоимости операций, входящих в состав процедуры)
CREATE TABLE TPROC_LIST (
 ID ID NOT NULL,
 ITEM_ID ID NOT NULL,
 PROCEDURE_ID ID NOT NULL,
 COST MONEY NOT NULL);


в состав процедуры могут входить только определенные операции из данной таблицы
CREATE TABLE TOPERATIONS (
 ID ID NOT NULL,
 NAME STRING120 NOT NULL,
 COST MONEY NOT NULL);


содержание каждой процедуры хранится здесь
CREATE TABLE TPROC_CONTENT (
 ID ID NOT NULL,
 PROC_ID ID NOT NULL,              --ид процедуры
 OPERATION_ID ID NOT NULL,      --ид операции
 AMOUNT ANUMBEROF NOT NULL, --количество операций в процедуре
 PROC_TYPE ID NOT NULL);         --тип процедуры, здесь ошибка, он должен быть в таблице TPROC_LIST, но что имеем


нужен запрос, возвращающий
item_id, model, comments, cost1, cost2, cost3 ... costn
где costn - стоимость процедуры n-го типа над данным предметом. это в общем случае, у меня задача
полегче - всего 4 типа процедур, значит нужно определить 4 стоимости.

Я создал 4 представления по типу:

CREATE VIEW COST1(
 ITEM_ID,
 COST)
AS
select i.ITEM_ID item_id
    , sum(pc.amount*o.cost) cost
 from titem i
    , toperations o
    , tproc_list pl
    , tproc_type pt
    , tproc_content pc
where pl.item_id = i.item_id --связываем список процедур со списком предметов
  and pl.procedure_id = pc.proc_id --связываем список процедур с их содержанием
  and o.id = pc.operation_id --связываем содержание процедур с операциями
  and pt.id = pc.proc_type --связываем тип процедуры с содержанием (здесь ошибка в структуре)
  and pc.proc_type = 1 --выбираем жестко прошитый тип процедуры
group by i.item_id; группируем, чтобы подсчитать сумму


Каждое представление возвращает item_id, cost. Дальше 4 представления нужно объеденить и здесь я пришел к full join (т.к. не для каждого предмета все процедуры заданы), а затем к left join.
select i.item_id
      , c1.cost cost1
      , c2.cost cost2
      , c3.cost cost3
      , c4.cost cost4
 from titem i
  left join cost1 c1 on i.id = c1.item_id
  left join cost2 c2 on i.id = c2.item_id
  left join cost3 c3 on i.id = c3.item_id
  left join cost4 c4 on i.id = c4.item_id


Если кто подскажет, как объеденить мне эти представления в один запрос, буду признателен.


 
Виталий Панасенко   (2009-07-28 12:20) [17]

для "скалы" не скажу, но для ЖарПтицы реально примерно так
execute block
returns
(item_id bigint, model varchar(50),
comments varchar(180),
cost1 numeric(18,2),
cost2 numeric(18,2),
cost3 numeric(18,2),
cost4 numeric(18,2)
as
declare variable i integer;
cost numeric(18,2);
begin
for
  select item_id, model, comments from titem
  into :item_id, :model, :comments do
   begin
     I = 1;
     for
      select first 4 -- Выбираем гарантировано не более 4 типов процедур
        cost from tproc_list order by procedure_id
       into :cost
        do
         begin
            if (I=1) then cost1 = :cost;
            if (I=2) then cost2 = :cost;
            if (I=3) then cost3 = :cost;
            if (I=4) then cost4 = :cost;
            I = I + 1;
            suspend;
         end
   end
end;


 
_drug_   (2009-07-28 13:09) [18]


> Виталий Панасенко  

у меня ЖарПтица 1_5, и execute block не поддерживается ((
придется делать процедуру.
С таким подходом нужно будет триггеры делать на обновление поля cost в tproc_list, но это нормально. но вот связь между значением I и реальным типом процедуры косвенная, боюсь, что к модификации этот код будет очень чувствителен. но подход для меня интересный. и еще я подумал - код работать не будет, нужно  select first 4 делать из tproc_type... но я понял, куда можно копать - в сторону ХП. ))) зачем извращаться с селектами, если можно сделать на ХП?


 
Виталий Панасенко   (2009-07-28 14:03) [19]

спросонья подумал, что СУБД - MS SQL... а на счет
> и еще я подумал - код работать не будет, нужно  select first
> 4 делать из tproc_type

интересно, как тогда связать TPROC_TYPE с TITEM?!!! связь есть только в TPROC_LIST. можно, конечно, связать эти 3 таблицы, но смысл? если уж связывать, то TITEM, TPROC_LIST и TOPERATIONS для расчета COST по TOPERATIONS.COST, чтобы не было нужды в
> С таким подходом нужно будет триггеры делать на обновление
> поля cost в tproc_list


 
turbouser___   (2009-07-28 14:34) [20]


> _drug_

А так?
select i.ITEM_ID item_id ,
sum(case WHEN pt.id=1 then pc.amount*o.cost ELSE 0 end) AS cost1,
sum(case WHEN pt.id=2 then pc.amount*o.cost ELSE 0 end) AS cost2,
sum(case WHEN pt.id=3 then pc.amount*o.cost ELSE 0 end) AS cost3,
sum(case WHEN pt.id=4 then pc.amount*o.cost ELSE 0 end) AS cost4
from titem i
   , toperations o
   , tproc_list pl
   , tproc_type pt
   , tproc_content pc
where pl.item_id = i.item_id --связываем список процедур со списком предметов
 and pl.procedure_id = pc.proc_id --связываем список процедур с их содержанием
 and o.id = pc.operation_id --связываем содержание процедур с операциями
 and pt.id = pc.proc_type --связываем тип процедуры с содержанием (здесь ошибка в структуре)
 and pc.proc_type = 1 --выбираем жестко прошитый тип процедуры
group by i.item_id; группируем, чтобы подсчитать сумму


 
_drug_   (2009-07-28 15:30) [21]


> если уж связывать, то TITEM, TPROC_LIST и TOPERATIONS для
> расчета COST по TOPERATIONS.COST

Совершенно верно.


> turbouser___  

если только убрать привязку к proc_type:
...and pc.proc_type = 1...
работает! и ХП не надо и ресурсов потребляет намного меньше, еще индекс настрою и вообще будет хрошо. век живи, век учись. а ведь просто все ))) Благодарю!



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2010.12.05;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.003 c
15-1282654644
Baks
2010-08-24 16:57
2010.12.05
Как можно передать параметр-строку на кириллице в PHP скрипт?


2-1284292105
rosl
2010-09-12 15:48
2010.12.05
управление


15-1282763419
Desdechado
2010-08-25 23:10
2010.12.05
Каптча в стиле дзен


6-1230204686
Calligraff
2008-12-25 14:31
2010.12.05
Организация события OndblClick для TPageControl


10-1171452145
vs_on
2007-02-14 14:22
2010.12.05
Автофильтр в Excel





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский