Почему СОЕДИНЕНИЕ использования, а не внутренние запросы

Я нахожу меня не желающим продвинуть к использованию СОЕДИНЕНИЯ, когда я могу легко решить ту же проблему при помощи внутреннего запроса:

например.

SELECT COLUMN1, ( SELECT COLUMN1 FROM TABLE2 WHERE TABLE2.ID = TABLE1.TABLE2ID ) AS COLUMN2 FROM TABLE1;

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

ОБНОВЛЕНИЕ

Я хочу добавить, что существует некоторая большая обратная связь в здесь, которая в сущности продвигает вернуться к использованию СОЕДИНЕНИЯ. Я нахожу меня все меньше и меньше связанным с использованием TSQL непосредственно в эти дни с результата решений ORM (LINQ к SQL, NHibernate, и т.д.), но когда я делаю это - вещи как связанные подзапросы, которые я нахожу, легче вывести линейно.

7
задан Keith Adler 24 February 2010 в 17:52
поделиться

8 ответов

Лично мне это невероятно трудно читать. Это не та структура, которую ожидает разработчик SQL. Используя JOIN, вы храните все источники ваших таблиц в одном месте, а не распределяете их по всему запросу.

Что произойдет, если вам понадобится три или четыре соединения? Помещать все это в предложение SELECT будет непросто.

8
ответ дан 6 December 2019 в 06:14
поделиться

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

И я считаю, что объединение намного проще читать и поддерживать.

6
ответ дан 6 December 2019 в 06:14
поделиться

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

6
ответ дан 6 December 2019 в 06:14
поделиться

Это неплохая практика программирования. вообще ИМО, это немного некрасиво. На самом деле это может быть повышение производительности в ситуациях, когда подвыбор из очень большой таблицы, в то время как вы ожидаете очень маленький набор результатов (вы должны учитывать индексы и платформу, 2000 с другим оптимизатором и все с 2005 года). Вот как я его форматирую, чтобы было легче читать.

select
  column1
  [column2] = (subselect...)
from
  table1

Изменить: Это, конечно, предполагает, что ваш подзапрос будет возвращать только одно значение, в противном случае он мог бы вернуть вам плохие результаты. См. Ответ gbn.

1
ответ дан 6 December 2019 в 06:14
поделиться

Можно сохранить последовательность начиная с конца. Так как вы, кажется, уже знаете maxSize...

Так что в основном, если файл изначально был (foo.txt)

[] [] [] [] [] [f] [o] [o] [.] [t] [x] [t] [\0]
             ^
             |
          lastEmpty           

Теперь, если вы добавляете родителя dir a/это будет выглядеть как

[] [] [] [a] [/] [f] [o] [o] [.] [t] [x] [t] [\0]
       ^      
       |      
    lastEmpty           

Так что код будет выглядеть что-то вроде (могут быть ошибки, но вы получаете идею).

char temp[LENGTH], file[LENGTH]; 
int lastEmpty = put_at_end(some_file_name, file);  
// lastEmpty points to right most empty slot

while (some_condition) { 
    parent_dir = some_calculation_that_yields_name_of_parent_dir; 

    int len = strlen(parent_dir);
    char *tmp = parent_dir + len -1;

    while (lastEmpty > 0) {
        file[lastEmpty] = *tmp;
        lastEmpty --;
        tmp--;
    }
} 

Поскольку я полагаю, что мы можем ожидать, что parent_dir будет небольшой, то два раза пройти через это должно быть нормально. Если вы хотите передать файл последовательности, вы можете просто использовать file + lastEmpty + 1 .

-121--1339989-

Пытались ли вы вообще не изменять файл test.cpp, но вместо этого при компиляции также сказать:

-I/usr/include/gfc2/
-121--4349257-

это значительно облегчает использование других типов соединений (левого внешнего, перекрестного и т.д.), потому что синтаксис для тех, кто в терминах подзапроса, менее чем идеален для читаемости

0
ответ дан 6 December 2019 в 06:14
поделиться

Это не эквивалент JOIN.

Если у вас есть несколько строк в TABLE2 для каждой строки в TABLE1, вы не получите их. Для каждой строки в TABLE1 вы получите один вывод строки, поэтому вы не можете получить несколько строк из TABLE2.

Вот почему я бы использовал "JOIN": чтобы убедиться, что я получаю нужные мне данные ...

После вашего обновления: я редко использую корреляцию, кроме EXISTS ...

{{1} }
4
ответ дан 6 December 2019 в 06:14
поделиться

Используемый вами запрос часто использовался вместо LEFT JOIN для движков, в которых он отсутствовал (в первую очередь, PostgreSQL до 7.2 )

Этот подход имеет ряд серьезных недостатков:

  1. Он может потерпеть неудачу, если TABLE2.ID не UNIQUE

  2. Некоторые движки не смогут использовать ничего, кроме NESTED LOOPS для этого запроса

  3. Если вам нужно выбрать более одного столбца, вам нужно будет написать подзапрос несколько раз

Если ваш движок поддерживает LEFT JOIN , используйте LEFT ПРИСОЕДИНЯЙТЕСЬ .

В MySQL , однако, есть некоторые случаи, когда агрегатная функция в подзапросе уровня выбора может быть более эффективной, чем в LEFT JOIN с GROUP BY .

См. Эту статью в моем блоге для примеров:

4
ответ дан 6 December 2019 в 06:14
поделиться

В конце концов, цель при написании кода, помимо функциональных требований, состоит в том, чтобы сделать намерение вашего кода понятным для читателя. Если вы используете JOIN, замысел очевиден. Если вы используете подзапрос таким образом, как вы описали, возникает вопрос, почему вы сделали это именно так. Чего вы пытались достичь, чего не смог бы добиться JOIN? Короче говоря, вы тратите время читателя, пытаясь определить, решал ли автор какую-то проблему гениальным способом или писал код после тяжелой ночи пьянства.

0
ответ дан 6 December 2019 в 06:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: