Вопрос SQL: имеет ли значение порядок предложения WHERE / INNER JOIN при связывании таблицы? - PullRequest
0 голосов
/ 21 мая 2019

Экзаменационный вопрос (AQA A-level Computer Science):
[Первичные ключи показаны звездочками]

Athlete(*AthleteID*, Surname, Forename, DateOfBirth, Gender, TeamName)
EventType(*EventTypeID*, Gender, Distance, AgeGroup)
Fixture(*FixtureID*, FixtureDate, LocationName)
EventAtFixture(*FixtureID*, *EventTypeID*)
EventEntry(*FixtureID*, *EventTypeID*, *AthleteID*)

Должен быть составлен список имен всех спортсменов, участвующих в матче. это происходит 17/09/18. В списке должны быть указаны фамилия, имя и Дата рождения этих спортсменов и никаких других подробностей. Список должен быть представлен в в алфавитном порядке по фамилии.

Напишите запрос SQL для создания списка.

Я понимаю, что вы можете сделать это двумя способами: один с помощью предложения WHERE, а другой с помощью предложения INNER JOIN. Однако мне интересно, имеет ли значение порядок при связывании таблиц.

Первое примерное решение:

SELECT Surname, Forename, DateOfBirth
FROM Athlete, EventEntry, Fixture
WHERE FixtureDate = "17/09/2018"
 AND Athlete.AthleteID = EventEntry.AthleteID
 AND EventEntry.FixtureID = Fixture.FixtureID
ORDER BY Surname

Вот первое примерное решение, было бы по-прежнему правильно, если бы я изменил порядок таблиц в предложении WHERE, например:

WHERE FixtureDate = "17/09/2018"
AND EventEntry.AthleteID = Athlete.AthleteID
AND Fixture.FixtureID = EventEntry.FixtureID

У меня тот же вопрос к предложению INNER JOIN, вот второе примерное решение:

SELECT Surname, Forename, DateOfBirth
FROM Athlete 
INNER JOIN EventEntry ON Athlete.AthleteID = EventEntry.AthleteID 
INNER JOIN Fixture ON EventEntry.FixtureID = Fixture.FixtureID
WHERE FixtureDate = "17/09/2018"
ORDER BY Surname

Опять-таки, было бы правильно, если бы я использовал этот порядок:

INNER JOIN EventEntry ON Fixture.FixtureID = EventEntry.FixtureID

Если порядок имеет значение, может кто-нибудь объяснить мне, почему он находится в порядке, показанном в примерах?

Ответы [ 3 ]

1 голос
/ 21 мая 2019

Несколько советов:

  • Никогда не используйте запятые в предложении FROM. Всегда используйте правильный, явный, стандартный JOIN синтаксис.
  • Используйте псевдонимы таблиц, которые являются аббревиатурами для имен таблиц.
  • Используйте стандартные форматы даты!
  • Указать все имена столбцов.

Тогда порядок сравнений не имеет значения для равенства. Я бы порекомендовал использовать канонический порядок.

Итак, запрос должен выглядеть примерно так:

SELECT a.Surname, a.Forename, a.DateOfBirth
FROM Athlete a INNER JOIN
     EventEntry ee
     ON a.AthleteID = ee.AthleteID INNER JOIN
     Fixture f
     ON ee.FixtureID = f.FixtureID
WHERE a.FixtureDate = '2018-09-17'
ORDER BY a.Surname;

Я предполагаю, что все столбцы в SELECT взяты из Athlete. Если это не так, настройте псевдонимы таблицы.

0 голосов
/ 24 мая 2019

При использовании внутренних объединений порядок не имеет значения, если таблица предпосылок находится выше / раньше. В вашем примере оба объединения начинаются со таблицы Athlete, поэтому порядок не имеет значения. Однако, если этот самый запрос найден, начиная с EventEntry (по любой причине), вы должны присоединиться к Атлету на первом внутреннем элементе, иначе вы не сможете присоединиться к Fixture. В соответствии с рекомендациями, лучше всего использовать стандартный синтаксис объединения и предпочтительнее размещать все внутренние объединения перед всеми левыми. Если вы не можете это сделать, вам нужно пересмотреть, потому что левые, которые вы должны поместить в группу внутренних соединений, вероятно, будут вести себя как внутреннее соединение. Это потому, что внутренняя часть ниже использует левую таблицу, иначе вы можете разместить ее под внутренним блоком. Поэтому, когда дело доходит до нуля, с левым будет все в порядке, но внутренняя часть снизу обрежет запись.

Если, однако, вышеприведенные случаи не существуют / не влияют на порядок, и все внутренние объединения могут быть размещены в любом порядке, важна только производительность. Обычно столы с большим количеством элементов наверху работают лучше, в то время как есть случаи, когда лучше работает противоположность. Поэтому, если заказ свободный, вы можете попробовать увеличить порядок таблиц кардинальности или наоборот - все работает быстрее.

Уточнение: в качестве обязательной таблицы я называю таблицу, необходимую для объединяемой таблицы, по условию: ... объединить B в [что угодно] объединить C в c.id = b.cid - здесь таблица B является обязательной для таблицы C.

Я упоминаю левые объединения, потому что, хотя вопрос касается внутреннего порядка, когда объединения смешаны (внутренние и левые), важен только порядок соединений (как все выше), поскольку это может повлиять на логику запроса: ... присоединиться к B на [любом] левом соединении C на c.id = b.cid присоединиться к D на D.id = C.did В приведенном выше примере левое соединение пробирается во внутренний порядок соединений. Мы не можем упорядочить его после D, потому что это является обязательным условием для D. Однако для записей, где условие c.id = b.cid неверно, вся строка таблицы B становится нулевой, а затем вся строка результата (B + C + D) выключается. результаты из-за условия D.id = C.did следующего внутреннего соединения. Этот пример нуждается в пересмотре, так как цель левого соединения испаряется с помощью следующего (следующего по порядку) внутреннего соединения. В заключение, порядок внутренних соединений при смешивании с левыми лучами должен быть сверху без вмешательства левых соединений.

0 голосов
/ 21 мая 2019

Существует множество стилистических соглашений для SQL, и в ответе @ gordonlinoff упоминаются некоторые из вечных.

На ваш вопрос есть несколько ответов.

Наиболее важным является то, что (условно) SQL является декларативным языком - вы говорите ему, что вы хотите, чтобы он делал, а не как это делали. В процедурном языке (таком как C, Java или PHP) порядок выполнения действительно имеет значение - последовательность инструкций является частью процедуры. На декларативном языке порядок не имеет значения.

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

Поскольку порядок не имеет значения, но правильное понимание цели запроса имеет значение, многие разработчики SQL подчеркивают удобочитаемость. Вот почему нам нравится явный синтаксис объединения и значимые псевдонимы. И для удобства чтения последовательность инструкций может помочь. Я предпочитаю начинать с «самой важной» таблицы, обычно той, из которой вы выбираете большинство столбцов, а затем следовать логической цепочке соединений из одной таблицы в другую. Это облегчает следование логике.

...