Как работает Self-Join MYSQL?
Недавно я задал вопрос о Self-Joins, и я получил отличный ответ.
Запрос предназначен для поиска идентификатора, начальной даты и цены события2, следующего за событием1 на 1 день.
Код WORKS отлично. Но я не понимаю, КАК.
Может кто-нибудь объяснить так тщательно, как вы можете, какие разные части запроса и что они делают?
SELECT event2.id, event2.startdate, event2.price
FROM mm_eventlist_dates event1
JOIN mm_eventlist_dates event2
ON event2.startdate = date_add(event1.enddate, INTERVAL 1 DAY)
WHERE event1.id=$id
Я очень ценю вашу помощь, по какой-то причине мне очень тяжело обволакивает это.
Ответы
Ответ 1
То, как я попытаюсь понять это, состоит в том, чтобы выписать два списка на один фрагмент event1 и один event2. Затем перечислите несколько записей в каждом списке (списки будут идентичными) теперь начинаются с WHERE в описании ниже.
Мы берем данные из двух таблиц (одна и та же таблица используется дважды, но на данный момент пытаюсь игнорировать)
FROM mm_eventlist_dates event1
JOIN mm_eventlist_dates event2
Это, вероятно, помогает читать остальное снизу вверх.
WHERE event1.id=$id
Итак, мы хотим, чтобы запись из события1 имела указанный идентификатор записи. Предположительно, что ровно одна запись. Теперь мы выяснили, что после этого события закончилось.
date_add(event1.enddate, INTERVAL 1 DAY)
Теперь, когда нам сообщаются записи из event2, они должны начинаться с этой даты,
ON event2.startdate = date_add(event1.enddate, INTERVAL 1 DAY)
Теперь у нас есть две записи, какие поля мы хотим?
SELECT event2.id, event2.startdate, event2.price
О, просто поля из тех, чья дата начала мы выяснили.
Ответ 2
Когда вы создаете соединение в запросе, вы буквально делаете это - объединяя 2 таблицы вместе. Это может быть 2 разных или 2 одинаковых таблицы, это не имеет значения. При указании соединения создание псевдонима для таблицы (имя, которое относится к нему в остальной части запроса) полезно, если таблицы разные, и существенные, если они одинаковы. Ваш запрос принимает таблицу 1 (event1), которая имеет столбцы:
event1.id, event1.startdate, event1.price
и соединение таблицы 2 (событие2):
event2.id, event2.startdate, event2.price
который оставляет вас с результирующим набором:
event1.id, event1.startdate, event1.price, event2.id, event2.startdate, event2.price
Критерии для соединения указаны как:
ON event2.startdate = date_add(event1.enddate, INTERVAL 1 DAY)
который говорит: "Для каждой строки в событии1 присоедините строки (строки) в событии2, который имеет начальную дату в 1 день после начальной даты в событии1
Затем, поскольку вас интересуют только данные для одного события, предложение where ограничивает набор результатов.
WHERE event1.id=$id
Наконец, поскольку вам не нужна информация из события 1 об исходном событии, ваш оператор select просто выбирает столбцы event2 из набора результатов:
SELECT event2.id, event2.startdate, event2.price
Ответ 3
Самообслуживание работает, ссылаясь на одну и ту же таблицу дважды, используя разные критерии выбора. Подумайте о каждой ссылке на таблицу как на другую "Виртуальную таблицу", созданную путем фильтрации исходной таблицы. Как правило, одна из таблиц "фильтруется" с использованием предложения WHERE, а вторая "фильтруется" в предложении соединения. Это наиболее эффективный способ сделать это, также можно "фильтровать" оба в предложении join.
Итак, у нас есть две виртуальные таблицы, основанные на данных в одной и той же базовой таблице, и они объединены вместе, как если бы они были двумя полностью отдельными таблицами.
Суть его в том, что вы храните данные в одной таблице, которая имеет немного другое значение, основанное на контексте.
Рассмотрим таблицу людей, каждая из которых имеет уникальный идентификатор и столбец для отца
id name fatherID
1 Joseph [null]
2 Greg 1
SELECT child.name as childName, father.name as fatherName
FROM people as child
INNER JOIN people as father on (child.fatherID = father.id)
Уступит 1 строку
childName fatherName
Greg Joseph
Ответ 4
Соединение объединяет две таблицы, основанные на определенных критериях. Критерии - это то, что следует за предложением ON.
Если вы присоединитесь к таблице с самим собой, она фактически будет такой же, как создание копии таблицы, переименуйте ее и выполните объединение с этой копией.
Например
Table foo Table bar
+---+---+---+ +---+---+---+
| a | b | c | | a | d | e |
+---+---+---+ +---+---+---+
| 1 | 2 | 3 | | 1 | 0 | 0 |
+---+---+---+ +---+---+---+
| 1 | 3 | 4 | | 2 | 9 | 3 |
+---+---+---+ +---+---+---+
| 1 | 3 | 5 |
+---+---+---+
| 2 | 4 | 6 |
+---+---+---+
Если мы делаем
select * from foo join bar on (foo.a = bar.a and foo.c > 4)
мы получим
foo join bar on (foo.a = bar.a and foo.c > 4)
+---+---+---+---+---+
| a | b | c | d | e |
+---+---+---+---+---+
| 1 | 3 | 5 | 0 | 0 |
+---+---+---+---+---+
| 2 | 4 | 6 | 9 | 3 |
+---+---+---+---+---+
Теперь,
SELECT event2.id, event2.startdate, event2.price
FROM mm_eventlist_dates event1
JOIN mm_eventlist_dates event2
ON event2.startdate = date_add(event1.enddate, INTERVAL 1 DAY)
WHERE event1.id=$id
этот запрос следует тому же принципу, но с двумя экземплярами таблицы mm_eventlist_dates, один с псевдонимом как event1, а другой как event2. Мы можем думать об этом как о двух таблицах и выполнить объединение так же, как в сценарии реальных двух таблиц.
Критерии присоединения в этом случае заключаются в том, что для table event2 стартовая комбинация соответствует enddate плюс один день таблицы event1.
Предложение where ограничивает то, что было выполнено в соединении, в этом случае он выполняет соединение только по строкам таблицы event1 с предоставленным идентификатором.