![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Составной SQL-запрос [D2005, XP]
Артемка © (2015-06-29 16:32:00)Здравствуйте мастера! У меня в базе MySQL есть две таблички: перечень товаров и мин.кол.(лимиты) товаров. Как составить запрос который бы отображал товары из перечня количество которых меньше указанного во второй таблице? Хочу просмотреть нарушенные лимиты, никак не могу придумать составной запрос блин...
Kilkennycat (2015-07-05 02:53:00) [1]
> Юрий Зотов © (03.07.15 11:21) [26]
> Достаточно лишь перевести на русский несколько английских слов - и смысл становится очевидным.
Да. Например: inner, left, right, full, outer, cross.
Кроме того, автору пофиг, ему нужно было бесплатное готовое решение.
Ну а ваще, если давать не готовое, а помогать находить (то есть, помогать научиться), то следует предлагать все варианты.
Кщд (2015-07-03 17:25:00) [2]>Игорь Шевченко © (03.07.15 14:33) [30]
согласен
осознал, раскаиваюсь)
Ega23 (2015-07-03 14:35:00) [3]
> вы пишете не в ANSI, а конкретных СУБД. Читать надо их
Не вопрос. Я ещё на той странице просил дать ссылку, либо на ansi, либо на оф.документацию к какой-либо серьёзной СУБД.
Игорь Шевченко (2015-07-03 14:33:00) [4]Кщд © (03.07.15 12:46) [28]
Прошу прощения за оффтопик, но жизнь слишком коротка, чтобы тратить время на переубеждение несогласных.
backuper (2015-07-03 13:44:00) [5]вы пишете не в ANSI, а конкретных СУБД. Читать надо их
Кщд (2015-07-03 12:46:00) [6]>backuper (03.07.15 12:14) [27]
оба варианта правильны
более того, они одинаковы
а сумрак и бестолковые догмы из головы можно вытравить чтением стандарта ANSI
backuper (2015-07-03 12:14:00) [7]
> Поэтому ответ надо давать не только правильный, а еще и
> ему понятный.
Архангельский давал, что о нем говорят повзрослевшие программисты - мы уже знаем.
Вопрос был не академическим, а практическим. Потому вопрос о букводски-правильности и понятности, на мой взгляд, перевешивает к первому.
Юрий Зотов (2015-07-03 11:21:00) [8]Надо еще учитывать, что если у человека возникла ТАКАЯ проблема, значит его знания SQL близки к нулю. Поэтому ответ надо давать не только правильный, а еще и ему понятный.
И с этой точки зрения запрос без join выигрывает, потому что для его понимания SQL можно и вообще не знать. Достаточно лишь перевести на русский несколько английских слов - и смысл становится очевидным.
Кщд (2015-07-03 09:32:00) [9]>backuper (01.07.15 17:21) [12]
1. это: "where T2.ID_T1 = T1.ID" - не декартово произведение
2.
Это
select t1.Id, t2.* from
t1, t2
where t2.t1id=t1.id
и
select t1.Id, t2.* from
t1 inner join t2 on (t2.t1id=t1.id)
эквивалентные операции и называются они - "внутреннее объединение"
3. "считают что это ничем не отличается от join": считать по-другому - редкостная ересь
не затруднит поделиться ссылочкой/источником, из которого были почерпнуты Ваши познания?
backuper (2015-07-02 08:57:00) [10]План запроса отражает ведь то, что сделает оптимизатор? Нужен более неудобный запрос чтобы показать потенциальную существенную разницу в этих запросах. MSSQL просто заменяет запрос на join, соответственно в плане отображается одно и то же.
http://s017.radikal.ru/i424/1507/4e/d1a1cee676ef.png
Ega23 (2015-07-02 08:45:00) [11]Короче, план запроса надо смотреть. :)
backuper (2015-07-02 08:17:00) [12]
> И дело тут даже не столько в древних методах доступа, сколько
> то, что в те времена действительно считалось, что во from
> идёт сбор данных по таблицам, а в where - их фильтрация.
>
Вот я и говорю - те люди что 20 лет назад поизучали основы sql до сих пор используют перечисление таблиц в from, и считают что это ничем не отличается от join (применительно к тем задачам, где можно кросс развернуть в джойн). Полагаю, ответ в таком заблуждении кроется в этом:
> А что там "по факту" - да пёс его знает. Формально набор
> данных будет одинаков.
результат работы запросабудет одинаков, но не сами запросы, так как кроме результата есть понятие ресурсозатратности. Вопрос банальной оптимизации. Понимание обычно приходит когда в запрос без оптимизатора попадают таблички с полумиллиардными наборами, правда многие сразу костыляют индексы, некоторые даже вспоминают про кластерные, а некоторые даже с удивлением узнают что использование функций по полю индексы отбрасывает и идет фулскан...
20 лет назад было все равно что писать - джойн или все в селекте.
Ega23 (2015-07-02 00:21:00) [13]
> В какой именно статье обосновано - сейчас сказать не могу,
> но это базовые вещи.
Я могу даже подсказать. Это в статье давности лет так 20, за авторством тех самых "людей далеко немолодых, частенько использующих древние методы доступа". И дело тут даже не столько в древних методах доступа, сколько то, что в те времена действительно считалось, что во from идёт сбор данных по таблицам, а в where - их фильтрация. Действительно ли они так считали, или они такие образные примеры приводили, чтобы мы, молодые и самоуверенные быстрее фишку прорубили - то мне неведомо.
А что там "по факту" - да пёс его знает. Формально набор данных будет одинаков. Но формально НД одинаков и у distinct и у group by без агрегата.
Кстати. В хелпе к MSSQL 7.x половина примеров на связки таблиц была с join-ом, а вот вторая - без, с условием в where. И в книгах всяких встречалось фифти-фифти.
backuper (2015-07-02 00:01:00) [14]
> А это уже совершенно не важно. Важно, что нет разницы.
вообще-то важно. То, что оптимизатор заменяетодин запрос выдавая его за другой (более оптимальный) - вовсе не делает первоначальный запрос равнозначным второму. И это вылезет на ближайшем запросе где оптимизатор не смог так же удачно помочь, либо в той среде, где оптимизатора вообще может не быть. Например mssql заменяет конструкцию предложенного запроса в этой теме на join, и обосновано (потому в скорости получения результата и в использовании ресурсов сервером разницы пользователь не видит). В какой именно статье обосновано - сейчас сказать не могу, но это базовые вещи.
Ega23 (2015-07-01 22:00:00) [15]
> оптимизатор?
А это уже совершенно не важно. Важно, что нет разницы.
backuper (2015-07-01 21:53:00) [16]
> План запроса - абсолютно одинаков (Firebird)
оптимизатор?
Ega23 (2015-07-01 21:49:00) [17]
> Что не отменяет того факта, что перечисление таблиц через
> запятую в селекте фактически означает CROSS JOIN.
Есть стандарт. Есть over9000 диалектов, в какой-то степени приближенных к стандарту. Приведи цитату из оф.документации, где сказано, что "перечисление таблиц через запятую в селекте фактически означает CROSS JOIN".
Из реальной БД:
select rg.id, rg.caption, r.id, r.caption as releasecaption
from releasegroups rg, releases_new r
where rg.id=r.relgrpid
select rg.id, rg.caption, r.id, r.caption as releasecaption
from releasegroups rg cross join releases_new r
where rg.id=r.relgrpid
select rg.id, rg.caption, r.id, r.caption as releasecaption
from releasegroups rg inner join releases_new r
on (rg.id=r.relgrpid)
т.е. без джоинов, cross join, inner join. План запроса - абсолютно одинаков (Firebird)
На других СУБД сейчас нет возможности прогнать, дома систему недавно переставлял, ещё не развернул.
Нюансов может быть вагон и маленькая тележка. Например, есть ли null-значения? Есть ли индексы по связующему полю? ну и ты.ды.
В общем, я бы не стал так категорично утверждать. Надо план запроса смотреть.
Игорь Шевченко (2015-07-01 21:41:00) [18]backuper (01.07.15 20:19) [15]
> Что не отменяет того факта, что перечисление таблиц через
> запятую в селекте фактически означает CROSS JOIN.
При отсутствии указания связи между таблицами в остальной части запроса.
backuper (2015-07-01 20:19:00) [19]
> Ega23 © (01.07.15 18:58) [14]
> Что значит "обычный" join? Есть 3 типа join-ов: inner,
> outer и cross. Outer делятся на 3 подвида: left, right и
> full.
> Как правило, ключевые слова "inner" и "outer" к написанию
> не обязательны.
>
> Поэтому запись "inner join" и "join" или "left outer join"
> и "left join" для большинства СУБД эквивалентна. Я inner
> пишу - да исторически так сложилось, отделяю от остальных.
Да, прошу прощения, в порыве желания макнуть ошибся и перепутал терминологию.
Что не отменяет того факта, что перечисление таблиц через запятую в селекте фактически означает CROSS JOIN.
Ega23 (2015-07-01 18:58:00) [20]
> джойн быстрее отработает. В общем случае, разумеется
Вот совершенно не факт. Зависит исключительно от реализации конкретной СУБД.
> не про inner join, прочитай чем отличается от "обычного" join
Что значит "обычный" join? Есть 3 типа join-ов: inner, outer и cross. Outer делятся на 3 подвида: left, right и full.
Как правило, ключевые слова "inner" и "outer" к написанию не обязательны.
Поэтому запись "inner join" и "join" или "left outer join" и "left join" для большинства СУБД эквивалентна. Я inner пишу - да исторически так сложилось, отделяю от остальных.