powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Хитрый запрос
12 сообщений из 12, страница 1 из 1
Хитрый запрос
    #32072744
Denis_M
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Народ, подскажите плиз. Имеются две таблицы, в одной хранятся имена городов, а в другой их численность. Эти таблицы связаны по ID города. Как вывести все города и их численности, но необходимо учесть, что не для всех городов есть численность (т.е. в таблицы численность не содержится ID этого города), т.е. для города у которого нет численности можно не выводить численность или вывести 0. Запрос не должен использовать UNION!!!!
...
Рейтинг: 0 / 0
Хитрый запрос
    #32072750
ShgGena
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
in 8i and 9i:

select c.city_id, c.city_name, p.population
from cities c, pops p
where c.city_id = p.city_id(+);

in 9i:

select c.city_id, c.city_name, p.population
from cities c left outer join pops p
on c.city_id = p.city_id;
...
Рейтинг: 0 / 0
Хитрый запрос
    #32072774
Denis_M
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо большое, помогло. Поясни плиз, если нетрудно.конструкцию where (+) в первом запросе, и from во втором.
...
Рейтинг: 0 / 0
Хитрый запрос
    #32072775
vskv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
(+) обозначает т.н. "внешнее соединение" (если не перепутал).

В кратце, ты заранее объявляешь, что с той стороны, где у тебя стоит "(+)" у тебя может и не быть значения для сравнения.
В твоём случае, это обозначает, что выбрать те строки, где c.city_id = p.city_id, и те строки где для c.city_id нет вообще соотв. значения в p.city_id. Причём для значений соотв. полей выбираемых из p используется значение NULL.

А второй вариант -- нетривиальное для понимания (сугубо моё IMHO) "извращение" пришедшее от MS SQL и Access.
Семантика одна и та же, но понять, какая из таблиц та "в которой нет соотв. значений ключа" достаточно сложно, так же как выделить названия полей, по которым идёт связка.
...
Рейтинг: 0 / 0
Хитрый запрос
    #32072794
ShgGena
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Второй вариант в точности соответсвует стандарту ANCI/ISO для SQL 92.
К счастью MS руку к этому стандарту практически не приложил.
Синтаксис INNER/OUTER JOIN пришел из IBM DB2 и он мощнее, чем
синтаксис Oracle.
В Oracle FULL OUTER JOIN можно было сделать тольку через UNION (до 9i), теперь в соответствии со стандартом что радует.
...
Рейтинг: 0 / 0
Хитрый запрос
    #32073200
Denis_M
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Так всё таки может поясните вторую конструкцию, и если можно то дайте ссылку, где про это можно почитать (желательно на русском). Заранее большое спасибо.
...
Рейтинг: 0 / 0
Хитрый запрос
    #32073217
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"in 9i:

select c.city_id, c.city_name, p.population
from cities c left outer join pops p
on c.city_id = p.city_id;"


А как сейчас решён вопрос в этой форме, который ранее при использовании "+" говорил, что столбец с этим знаком должен быть справа от "=", иначе оптимизатор не сможет оптимизировать запрос? Как правильно соединять теперь?
...
Рейтинг: 0 / 0
Хитрый запрос
    #32073731
vskv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вспомнил за что не люблю эти "JOIN" -- FROM становится абсолютно нечитаемым в случае если внешне связывается три и более таблицы.
У плюсиковой нотации в этом отношении плюс :), что явно видны все таблицы учавствующие в запросе.
...
Рейтинг: 0 / 0
Хитрый запрос
    #32074847
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Будь поосторожнее со сравнением данных вариантов синтаксиса, они немного разные. Пример:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
create table test (
    test_id integer
  , constraint pk_test primary key (test_id)
)
/
create table test2 (
    test_id integer
  , constraint pk_test2 primary key (test_id)
)
/

insert into test(test_id) values ( 1 );
insert into test(test_id) values ( 3 );

insert into test2(test_id) values ( 1 );
insert into test2(test_id) values ( 2 );
commit;

А теперь, запрос с (+), только с дополнительным условием по "внешней" таблице:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
dan@oraspb>; select t.test_id
   2        , t2.test_id test2_id
   3   from test t
   4      , test2 t2
   5   where  1 = 1 
   6     and t.test_id = t2.test_id (+)
   7     and t2.test_id =  2 
   8   /

no rows selected

запрос с left outer join:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
dan@oraspb>; select t.test_id
   2        , t2.test_id test2_id
   3   from test t
   4          left outer join test2 t2
   5            on t.test_id = t2.test_id
   6            and t2.test_id =  2 
   7   /

   TEST_ID   TEST2_ID
 ---------- ----------
 
          1 
          3 

Для достижения того же результата первый запрос следует переписать:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
dan@oraspb>; select t.test_id
   2        , t2.test_id test2_id
   3   from test t
   4      , (select * from test2 where test_id =  2 ) t2
   5   where  1 = 1 
   6     and t.test_id = t2.test_id (+)
   7   /

   TEST_ID   TEST2_ID
 ---------- ----------
 
          1 
          3 


Согласись, что он несколько потерял наглядность?
...
Рейтинг: 0 / 0
Хитрый запрос
    #32074895
va_kochnev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все наглядно:

select t.test_id
, t2.test_id test2_id
from test t
, test2 t2
where 1=1
and t.test_id = t2.test_id (+)
and nvl(t2.test_id,2) = 2
...
Рейтинг: 0 / 0
Хитрый запрос
    #32074972
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, это еще один способ корректировки запроса. Повторю лишь: стоит очень осторожно подходить к переписыванию запроса с одного синтаксиса на другой, можно получить различные результаты.

В Sybase и MSSQL для внешнего соединения используется символ * возле знака =; так вот, если мне не изменяет память, то при указании конкретного значения поля вов внешней таблице получаются данные, аналогичные оракловой реализации синтаксиса с outer join, а не синтаксиса с (+), что еще больше усложняет задачу переноса кода с одного сервера на другой. Если у кого есть вожможность, проверьте пожалуйста, я могу ошибаться.
...
Рейтинг: 0 / 0
Хитрый запрос
    #32075100
ОВГ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
>Denis Popov вчера, 19:22
чтобы первый запрос не терял наглядность, его стоит написать так:
select t.test_id,
t2.test_id test2_id
from test t,
test2 t2
where 1=1
and t.test_id = t2.test_id (+)
and t2.test_id (+)= 2
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Хитрый запрос
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]