Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: многотабличный запрос с использованием JOIN
 
 автор: Roma   (11.07.2007 в 20:14)   письмо автору
 
 

Помогите расшифровать запрос (т.е что с какой таблицы и в какой последовательности берется):

SELECT head, link, style FROM blocks JOIN block ON blocks.id_block=block.id;

Заранее спасибо

   
 
 автор: oradev   (11.07.2007 в 21:06)   письмо автору
 
   для: Roma   (11.07.2007 в 20:14)
 

>Помогите расшифровать запрос (т.е что с какой таблицы и в какой последовательности берется):
>
>SELECT head, link, style FROM blocks JOIN block ON blocks.id_block=block.id;
>
>Заранее спасибо

Внутреннее Соединение таблиц, а так хорошо бы структуру табличек глянуть

   
 
 автор: Roma   (11.07.2007 в 23:01)   письмо автору
 
   для: oradev   (11.07.2007 в 21:06)
 

Структура таблицы `block`


CREATE TABLE `block` (
  `id` int(11) NOT NULL auto_increment,
  `head` varchar(200) NOT NULL,
`link` varchar(200) NOT NULL,
  `style` varchar(50) NOT NULL default 'block_body',
  PRIMARY KEY  (`id`)


Структура таблицы `blocks`


CREATE TABLE `blocks` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(100) NOT NULL,
  `id_block` int(11) NOT NULL,
  PRIMARY KEY  (`id`)
)


PS А можно по подробнее: что с какой таблицы берется, по какой причине (JOIN)

   
 
 автор: Gust   (12.07.2007 в 08:39)   письмо автору
 
   для: Roma   (11.07.2007 в 23:01)
 

>PS А можно по подробнее: что с какой таблицы берется, по какой причине (JOIN)
В данном случае все поля поля берутся из таблицы `block`, но в отличии от простого селекта этих же полей в результат запроса попадут только те строки у которых имеется сопадение blocks.id_block=block.id, т.е. по сути будет равно количеству строк в таблице blocks (если ее поля id_block не имеют значения, отличные от значений block.id)

   
 
 автор: Trianon   (12.07.2007 в 10:45)   письмо автору
 
   для: Gust   (12.07.2007 в 08:39)
 

Строк в результате может быть меньше, если в таблице blocks не найдется подходящих.
И может быть больше, если в ней будет более одной записи на каждую выбираемую (id_block первичным ключом не является, так что это вполне реально)

На мой взгляд, запрос практического смысла не имеет. Именно из-за того, что не выбирается ничего из таблицы blocks.

   
 
 автор: oradev   (13.07.2007 в 02:25)   письмо автору
 
   для: Trianon   (12.07.2007 в 10:45)
 

Давайте по фактам, ваша фраза:
>На мой взгляд, запрос практического смысла не имеет. Именно из-за того, что не выбирается ничего из таблицы blocks.
Относительно запроса
SELECT head, link, style FROM blocks JOIN block ON blocks.id_block=block.id;

Вызывает у меня некое непонимание вами теории проектирования БД, а именно:

1) Из таблицы blocks как раз-таки все выбирается в этом случаи. Ну опечатка наверное!
2)Вы поймите что стоит применить магию как мы получим разные запросы

SELECT id_block,head, link, style FROM blocks JOIN block ON blocks.id_block=block.id;

SELECT id_block,head, link, style FROM blocks;

Второй запрос не всегда эквивалентен первому.

   
 
 автор: Trianon   (13.07.2007 в 02:47)   письмо автору
 
   для: oradev   (13.07.2007 в 02:25)
 

>Давайте по фактам, ваша фраза:
Ок.
>>На мой взгляд, запрос практического смысла не имеет. Именно из-за того, что не выбирается ничего из таблицы blocks.
>Относительно запроса SELECT head, link, style FROM blocks JOIN block ON blocks.id_block=block.id;
>Вызывает у меня некое непонимание вами теории проектирования БД, а именно:
>1) Из таблицы blocks как раз-таки все выбирается в этом случаи.

Выбираются поля head, link, style. Все они принадлежат таблице block.
Из таблицы blocks вышеприведенным запросом не выбирается ни одного столбца.


>2)Вы поймите что стоит применить магию как мы получим разные запросы
>SELECT id_block,head, link, style FROM blocks JOIN block ON blocks.id_block=block.id;
>SELECT id_block,head, link, style FROM blocks;
>Второй запрос не всегда эквивалентен первому.

Чтобы получить ошибку (unknown column head in field list) во втором запросе, совсем не обязательно применять магию. Естественно, корректный и ошибочный запрос друг другу не эквивалентны.

PS. На Вашем месте делать выводы о том, у кого и как обстоит с теорией проектирования БД я бы поостерегся.
Я, вот, не делаю, не смотря на то, что Вы тут насочиняли.

   
 
 автор: oradev   (13.07.2007 в 03:28)   письмо автору
 
   для: Trianon   (13.07.2007 в 02:47)
 

Я который раз убеждаюсь, что вы не хотите меня слушать, а пересказываете план выполнения запроса.

Я уже сказал, что опечатка в привиденном запросе автора топика, ясно что из таблицы block нужно выбирать перечисленные столбцы. А во вторых я пытаюсь до вас всю ночь довести, что

SELECT id,head, link, style FROM block JOIN blocks ON blocks.id_block=block.id;
SELECT id,head, link, style FROM block;

Это не одно и тоже. Вы суть то понимаете или нет.

   
 
 автор: Trianon   (13.07.2007 в 12:52)   письмо автору
 
   для: oradev   (13.07.2007 в 03:28)
 

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


>Я уже сказал, что опечатка в привиденном запросе автора топика,
Кто Вам это сказал? Автор?
Я ни Вашей трактовки текста запроса, ни подтверждения её автором топика не увидел.

>ясно что из таблицы block нужно выбирать перечисленные столбцы.
Запрос их именно оттуда и выбирает, судя по (11.07.2007 в 23:01)
С этим никто не спорит.

>А во вторых я пытаюсь до вас всю ночь довести, что

>SELECT id,head, link, style FROM block JOIN blocks ON blocks.id_block=block.id;
>SELECT id,head, link, style FROM block;
>Это не одно и тоже. Вы суть то понимаете или нет.

Это не одно и то же. Второй просто выведет таблицу.
Результатом первого будет ambigous column id.

Когда исправите ошибки, можем продолжить.

PS. Я очень сомневаюсь, что в теме соединений таблиц Вы сможете объяснить мне что-то, что я не знаю. В других темах - несомненно, с ораклом мне приходилось работать нечасто.
Но в этой - увы.

   
 
 автор: Roma   (12.07.2007 в 10:46)   письмо автору
 
   для: Gust   (12.07.2007 в 08:39)
 

Тогда два вопроса
1. Чем отличается данный запрос от
SELECT head, link, style FROM blocks, block where blocks.id_block=block.id;

2. А если был бы запрос такой:

SELECT head, link, style FROM blocks LEFT JOIN block ON blocks.id_block=block.id;


PS Может кто знает где доступно написано об этом, прошу дать ссылки

   
 
 автор: Roma   (12.07.2007 в 11:30)   письмо автору
 
   для: Roma   (12.07.2007 в 10:46)
 

Может быть кто-нибудь сможет на конкретном примере вкрации рассказать о JOIN-ах?
Очень надо, помогите пожалуйста

   
 
 автор: Gust   (12.07.2007 в 13:00)   письмо автору
 
   для: Roma   (12.07.2007 в 10:46)
 

>1. Чем отличается данный запрос от
>SELECT head, link, style FROM blocks, block where blocks.id_block=block.id;
>2. А если был бы запрос такой:
>SELECT head, link, style FROM blocks LEFT JOIN block ON blocks.id_block=block.id;

Скажем, если запись с полем blocks.id_block будет иметь значение, которое не встречается в полях block.id 1й запрос не включит данную запись в результат, 2ой - включит со значением полей head, link, style = NULL, при этом число записей будет соответствовать таблице blocks.

1й запрос будет аналогичен запросу
SELECT head, link, style FROM blocks JOIN block ON blocks.id_block=block.id;
т.е. выбирутся только совпадающие записи

Совсем другой результат получите при использовании Right JOIN: число записей будет соответствовать таблице block, а запрос будет аналогичен
SELECT head, link, style FROM block

>Может быть кто-нибудь сможет на конкретном примере вкрации рассказать о JOIN-ах?
полагаю Jonы следует применять когда требуется вывести в результат запроса поля из разных таблиц, которые можно соединить по типу blocks.id_block=block.id.
Я обычно ориентируюсь так
Выбираем Т1.Поле и Т2.Поле Из Т1 соедененной с Т2 при Т1.IDОтТ2 подставлемой из Т2.ID
(select Т1.Поле, Т2.Поле From Т1 left join Т2 on Т1.IDОтТ2=Т2.ID)

   
 
 автор: Roma   (12.07.2007 в 13:59)   письмо автору
 
   для: Gust   (12.07.2007 в 13:00)
 

Спасибо большое, Gust, вы очень понятно и доступно объяснили.
ЗЫ Может подскажите полезную ссылку на литературу по поводу JOIN-ов?

   
 
 автор: Roma   (12.07.2007 в 17:57)   письмо автору
 
   для: Roma   (12.07.2007 в 13:59)
 

тогда можо хотя бы пример, когда используется LEFT JOIN (вместе со структурой таблиц)

   
 
 автор: oradev   (13.07.2007 в 00:28)   письмо автору
 
   для: Roma   (12.07.2007 в 17:57)
 

>тогда можо хотя бы пример, когда используется LEFT JOIN (вместе со структурой таблиц)

В номенклатуре ANSI/SQL это выглядит вот так:


select e.ename, d.DEPTNO
from emp e LEFT OUTER JOIN dept d
ON e.DEPTNO = d.DEPTNO;


Или так:

select e.ename, d.deptno
from emp e RIGHT OUTER JOIN dept d
ON e.DEPTNO = d.DEPTNO;


где dept - таблица отелов, emp - таблица служащих в данных отделах ( из расчета служащий может работать только в одном департаменте)

   
 
 автор: oradev   (12.07.2007 в 23:31)   письмо автору
 
   для: Roma   (11.07.2007 в 23:01)
 

Судя по привиденным структурам таблиц, вы имеете
Таблицу block - родительская
Таблицу blocks - дочернюю

Вот этот запрос:
SELECT head, link, style FROM blocks JOIN block ON blocks.id_block=block.id;

выбирает соответствующие столбцы из дочерней таблицы blocks.

Но вы ограничиваете строки у которых внешний ключ id_block равен NULL
поскольку первичный ключ id таблицы block  ни при каких случаях не может быть равен NULL

   
 
 автор: Trianon   (13.07.2007 в 00:18)   письмо автору
 
   для: oradev   (12.07.2007 в 23:31)
 

>Но вы ограничиваете строки у которых внешний ключ id_block равен NULL
> поскольку первичный ключ id таблицы block ни при каких случаях не может быть равен

он может быть банально не найден.

   
 
 автор: oradev   (13.07.2007 в 00:24)   письмо автору
 
   для: Trianon   (13.07.2007 в 00:18)
 

>>Но вы ограничиваете строки у которых внешний ключ id_block равен NULL
>> поскольку первичный ключ id таблицы block ни при каких случаях не может быть равен
>
>он может быть банально не найден.

Остерегайтесь NULL с ним поверьте

не все так банально
, следить нужно за ним!
Ограничений нет никаких вот и следите сами его.

   
 
 автор: Trianon   (13.07.2007 в 00:28)   письмо автору
 
   для: oradev   (13.07.2007 в 00:24)
 

А что с ним не так?
Это уже начинает становиться забавным....

   
 
 автор: oradev   (13.07.2007 в 00:39)   письмо автору
 
   для: Trianon   (13.07.2007 в 00:28)
 

>А что с ним не так?
>Это уже начинает становиться забавным....


create table emp_copy
(job VARCHAR2(20));

insert into emp_copy values('CLERK');
insert into emp_copy values('MANAGER');
insert into emp_copy values(NULL);

select count(*) from emp_copy;

3
select count(job) from emp_copy;

2

   
 
 автор: Trianon   (13.07.2007 в 00:45)   письмо автору
 
   для: oradev   (13.07.2007 в 00:39)
 

Замечательно. Какое отношение имеет семантическое различие вызовов COUNT(column) и COUNT(*) к операции внутреннего соединения таблиц?

   
 
 автор: oradev   (13.07.2007 в 01:06)   письмо автору
 
   для: oradev   (12.07.2007 в 23:31)
 

>Судя по привиденным структурам таблиц, вы имеете
>Таблицу block - родительская
>Таблицу blocks - дочернюю
>
>Вот этот запрос:
>SELECT head, link, style FROM blocks JOIN block ON blocks.id_block=block.id;
>
>выбирает соответствующие столбцы из дочерней таблицы blocks.
>

>Но вы ограничиваете строки у которых внешний ключ id_block равен NULL
>поскольку первичный ключ id таблицы block  ни при каких случаях не может быть равен NULL
>


Читаете узнаете

   
 
 автор: Trianon   (13.07.2007 в 01:43)   письмо автору
 
   для: oradev   (13.07.2007 в 01:06)
 

Момент первый.
Строки таблицы blocks с внешним ключом id_block содержащим NULL вообще никак не повлияют на результат запроса, потому что соединение внутреннее, а равенство NULL тождественно равно false. И значит такие строки не образуют JOIN-ON соответствий в принципе.
Так что не "ограничиваете" а "исключаете".

Момент второй.
будут исключены все строки block, которым не нашлось подходящего id_blocks.
Это то, что я назвал "банально не найден".
Этого не случилось бы, будь соединение экзотическим правым внешним.

Момент третий.
строки block, которым нашлось несколько таких соответствий (ключ то чужой!) будут размножены одинаковыми. Они отличались бы, будь в списке полей SELECT хотя бы одно поле из левой таблицы.

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования