Как программно создать операторы JOIN? - PullRequest
2 голосов
/ 14 июля 2011

Технологии: VS.net 2008, C #, Winforms, SQL Server 2008

В настоящее время я нахожусь в процессе написания построителя Visual Select Query для работы, но я застрял на том, как создаются объединения,Я понимаю, как мне нужно делать их, когда я пишу их вручную, но я не уверен, как я могу перевести это в алгоритм.

В настоящее время мой построитель запросов select обладает всеми функциями получения таблиц, отображениястолбцы, выбирая, какие столбцы вы хотите, используя операторы «И, ИЛИ» для определенных столбцов, и он прекрасно выполняет запрос.Но как только появляется другая таблица, все чертовски разрушается.

Использование уже существующего приложения не подлежит сомнению, и ответы, которые предполагают, что другие продукты должны быть отклонены.

Существует ли жесткое и быстрое правило, которое гласит: «При написании оператора Join вы должны выполнять __ и __ и т. Д ...)

Я основал свою первоначальную концепцию на MSДоступ, и я заметил, что он использует все левые соединения, но я не понимаю, почему это происходит.

Ответы [ 2 ]

1 голос
/ 14 июля 2011

Не существует «жестких и быстрых» правил для такого рода вещей, потому что это очень сильно зависит от структуры данных.Я думаю, что вы хорошо начинаете наблюдать, как MS Access справляется с этим.Другими хорошими вариантами было бы создать образец конструктора Entity Framework или LINQ 2 SQL в конструкторе и наблюдать, как они переводятся в SQL на внутреннем сервере.(Дизайнер соединений EF, в частности, довольно умен и гибок).

Access использует в основном левые соединения, потому что они являются «самыми безопасными», учитывая абсолютно нулевое знание структуры исходных данных.Хитрость заключается в том, чтобы попытаться разработать инструмент, который соответствует ожиданиям вашего пользователя.В конструкторе запросов Access, если я выберу таблицу, а затем подключу ее к другой таблице, наиболее вероятным сценарием является «Я хочу получить все данные из этой таблицы, но мне тоже нужно извлечь данные из этой другой таблицы», то есть слева.присоединиться.Если было произведено внутреннее объединение, и я не получил все строки в первой таблице, это было бы удивительно.

Конечно, Access также позволяет вам исправить эти правила, если вам действительно нужно,Это лучший подход: создайте разумное значение по умолчанию, которое с наименьшей вероятностью может сбить с толку вашего пользователя, а затем предоставьте ему способ изменить значение по умолчанию, если они знают лучше.

Один из вариантов - это немного перевести язык объединения в нечтовысший уровень;например, если ваши пользователи вообще знакомы с моделированием данных, они могут распознать «один-ко-многим» (внутреннее объединение) или «один-к-ну-или-большему» (внешнее объединение).Возможно, даже сделайте так, чтобы операция, которая создает объединения в вашем компоновщике, использовала совершенно другие слова, такие как «Необязательная ссылка» против «Обязательная ссылка» или даже «Таблица поиска подключений» против «Объединить дочерние данные».Узнайте, какие слова или термины думают ваши пользователи, когда они используют ваш конструктор запросов, сопоставьте их с соответствующими типами JOIN и используйте их.Опять же, разработчик EF сопоставил концепцию SQL-соединений с высокоуровневой концепцией моделирования данных родительско-дочерних отношений, которая хорошо работает.

С технической точки зрения, существуют мои личные правила написания JOIN.Некоторые из них основаны на, возможно, устаревших или устаревших представлениях о том, как оптимизировать запросы и индексы, и, возможно, в них больше нет необходимости, но они мне хорошо послужили:

  • Всегда используйте синтаксис длинных форм соединения(нет ярлыков предложения WHERE
  • Поместите все критерии для строк дочерней таблицы в предложение ON, когда это возможно (то есть, в моих предложениях WHERE редко есть условия, включающие поля из таблиц с внутренним объединением)
  • Используйте ВНУТРЕННЕЕ СОЕДИНЕНИЕ там, где известно, что оно безопасно
  • Предпочитайте ЛЕВЫЕ СОЕДИНЕНИЯ и НЕ ПОЛУЧИТЕ подзапросам, когда это возможно.

РЕДАКТИРОВАТЬ:Меня исправили из-за неверного представления о том, что JOINS работают быстрее, чем подзапросы (конечно, вы все равно собирались выполнять свои собственные тесты производительности, верно? :))

1 голос
/ 14 июля 2011

Основные критерии, которые вы хотите знать:

  • С какими полями связаны таблицы?
  • Какие поля имеют неравенства?
  • Хотите ли вы ограничить количество результатов только совпадениями или включить несоответствия?

Первый критерий важен для вашего утверждения ON. Так же и второй. Нередко бывает запрос, в котором вы хотите увидеть результаты, в которых одни поля общие, а другие - нет, например:

SELECT a.LineId, a.Total, b.Subtotal
FROM TableA as A
INNER JOIN TableB as B
    ON b.subtotal = a.total
    AND b.ID <> a.LineId

Третий критерий - как узнать, хотите ли вы LEFT или INNER JOIN.

Если вы хотите видеть только совпадающие строки, используйте INNER. Если вы хотите увидеть все строки из первой таблицы, но показать совпадение со второй, когда она существует, используйте LEFT JOIN.

Вы также можете рассмотреть FULL OUTER объединений, которые показывают все результаты из обеих таблиц. CROSS JOIN не так широко используются, поэтому вам нужно будет определить, есть ли у вас сценарий их использования. Они показывают декартово произведение (т. Е. Все строки из таблицы A соответствуют всем строкам из таблицы B - все возможные комбинации).

Можете ли вы быть более точным в том, что вам нужно?

...