Я добавляю свой личный опыт, поскольку он кажется немного безопаснее, чем то, что было предложено в 2012 году:
brew doctor
. Если вы получите следующее предупреждение:
Warning: The /usr/local directory is not writable.
запустите:
sudo chown -R `whoami` /usr/local
, чтобы исправить проблемы с разрешениями (как предложено также Крисом Фрисиной). В конце концов, снова запустите brew doctor
, чтобы убедиться, что предупреждение исчезло.
Теперь у вас должен быть
Warning: You have uncommitted modifications to Homebrew
, который может быть решен с помощью
cd /usr/local/Library && git stash && git clean -d -f
, как это было предложено самим доктором Бру. Команда сохраняет незавершенные изменения, чтобы вы могли вернуться и восстановить их при необходимости. Это казалось мне безопаснее, чем git reset --hard origin/master
.
Если хотите, проверьте официальное руководство по устранению неполадок , если шаги, предложенные здесь и другими пользователями SO, не решают вашу проблему.
Ну, это порядок операций ..
SELECT
t1.*
FROM
table1 t1
INNER JOIN table2 t2
LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID
ON t2.table2_ID = t1.table1_ID
можно переписать как:
SELECT
t1.*
FROM
table1 t1 -- inner join t1
INNER JOIN
(table2 t2 LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID) -- with this
ON t2.table2_ID = t1.table1_ID -- on this condition
Итак, сначала вы НАЛЕВАЙТЕ СОЕДИНЯЙТЕСЬ t2 с t3, в зависимости от условия соединения: table3_ID = table2_ID , затем вы ВНУТРЕННЕЕ СОЕДИНЕНИЕ t1 с t2 на table2_ID = table1_ID.
В вашем втором примере вы сначала ВНУТРЕННЕЕ СОЕДИНЯЕТЕСЬ t1 с t2, а затем СОЕДИНЯЕТЕСЬ СЛЕВА с результирующим внутренним соединением с таблицей t3 при условии table2_ID = table1_ID.
SELECT
t1.*
FROM
table1 t1
INNER JOIN table2 t2 ON t2.table2_ID = t1.table1_ID
LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID
может быть переписанным как:
SELECT
t1.*
FROM
(table1 t1 INNER JOIN table2 t2 ON t2.table2_ID = t1.table1_ID) -- first inner join
LEFT JOIN -- then left join
table3 t3 ON t3.table3_ID = t2.table2_ID -- the result with this
РЕДАКТИРОВАТЬ
Прошу прощения. Мое первое замечание было неправильным. Два запроса дадут одинаковые результаты, но может быть разница в производительности, поскольку первый запрос может выполняться медленнее, чем второй запрос в некоторых случаях (когда таблица 1 содержит только подмножество элементов в таблице 2), поскольку LEFT JOIN будет сначала выполняться - и только потом пересекаться с table1.
Для вашего конкретного примера, я не думаю, что должна быть какая-либо разница в сгенерированных планах запросов, но определенно разница в удобочитаемости. Ваш второй пример НАМНОГО легче следовать.
Если бы вы изменили типы объединений в примере, вы могли бы получить совсем другие результаты.
SELECT t1.*
FROM table1 t1
LEFT JOIN table2 t2 ON t2.table2_ID = t1.table1_ID
INNER JOIN table3 t3 ON t3.table3_ID = t2.table2_ID
-- may not produce the same results as...
SELECT t1.*
FROM table1 t1
LEFT JOIN table2 t2
INNER JOIN table3 t3 ON t3.table3_ID = t2.table2_ID
ON t2.table2_ID = t1.table1_ID
Основываясь на том факте, что порядок объединений ДЕЙСТВИТЕЛЬНО имеет значение для многих case - следует тщательно продумать, как вы пишете синтаксис соединения. Если вы обнаружите, что второй пример - это то, что вы действительно пытаетесь выполнить, я бы подумал о переписывании запроса, чтобы вы могли больше внимания уделять порядку ваших объединений ...
SELECT t1.*
FROM table2 t2
INNER JOIN table3 t3 ON t3.table3_ID = t2.table2_ID
RIGHT JOIN table1 t1 ON t2.table2_ID = t1.table1_ID
Лучший способ увидеть, чем отличаются эти два запроса, - это сравнить план запроса для обоих этих запросов.
Нет никакой разницы в наборах результатов для этих IF в таблице 3 всегда есть строки для данной строки в таблице 2.
Я пробовал это в своей базе данных, и разница в планах запросов заключалась в том, что 1. Для первого запроса оптимизатор решил сначала выполнить объединение таблиц table2 и table 3. 2. Для второго запроса оптимизатор сначала решил объединить table1 и table2.
Вы не должны увидеть никакой разницы между двумя запросами, при условии, что ваш оптимизатор СУБД до нуля. Это, однако, даже для больших железных дорогостоящих платформ, не является предположением, в котором я был бы уверен, поэтому я не удивился бы, обнаружив, что планы запросов (и, следовательно, время выполнения) менялись.