Подзапрос, автоматически создающий перекрестное соединение

#sql #subquery #cross-join

#sql #подзапрос #перекрестное объединение #перекрестное соединение

Вопрос:

Я не уверен, ПОЧЕМУ, но когда я следую примеру (из базы данных northwind на сервере ms sql server), чтобы выполнить подзапрос в Microsoft SQL Server Management Studio 2008, введя код, как показано ниже,

 Select Orders.OrderID, 
       (Select Customers.CompanyName 
          From Customers 
          Where Customers.CustomerID = Orders.CustomerID) As Company Name
  From Orders, 
       Customers
  

Этот sql-код с подзапросом автоматически получил перекрестное соединение и стал

     Select Orders.OrderID,
           (Select Customers.CompanyName 
              From Customers
             Where Customers.CustomerID = Orders.CustomerID) As Company Name
      From Orders 
CROSS JOIN Customers as Customers_1
  

Я поиграл с несколькими вариантами этого, но безуспешно в устранении этой проблемы. Является ли это известной ошибкой для Microsoft sql server management studio 2008? Если да, было ли оно исправлено, как мне найти исправленное? В противном случае, как я могу сообщить об этом в Microsoft и заставить их действительно быстро это исправить?

В моем фактическом запросе мне нужно запросить / просмотреть имя этой конкретной таблицы примерно 50 раз, приравнивая идентификатор, и я думаю, что просто глупо выполнять для этого какое-либо объединение, потому что код корявый, ОЧЕНЬ длинный, и производительность может быть низкой?

Комментарии:

1. Запросы эквивалентны — первый использует синтаксис ANSI-89, второй использует синтаксис ANSI-92. Подвыборка не меняет того, что существует декартово произведение ЗАКАЗОВ и КЛИЕНТОВ…

Ответ №1:

Перекрестное соединение вызывается не подзапросом, а отсутствием условия, управляющего соединением. Вам нужно что-то вроде этого:

 Select Orders.OrderID, (Select Customers.CompanyName From Customers Where Customers.CustomerID = Orders.CustomerID) As Company Name 
From Orders, Customers
Where Orders.CustomerID = Customers.CustomerID
  

Комментарии:

1. спасибо вам, сэр, за ваш любезнейший ответ, но разве цель выполнения подзапроса не в том, что я могу выполнить управление условием внутри подзапроса, ТОЛЬКО не нужно повторять это снова в предложении WHERE основного выбора???

2. но разве цель выполнения подзапроса не в том, чтобы я мог выполнять управление условием только внутри подзапроса и мне не нужно было повторять это снова в предложении main Select WHERE??? в противном случае, мне нужно «выполнить поиск / запрос» этой конкретной таблицы 50 раз, и предложение Where было бы похоже на Where (Orders.CustomerID = Клиенты. CustomerID) и (Orders.CustomerID1 = Клиенты. CustomerID) и (Orders.CustomerID2 = Клиенты. CustomerID) и … Наконец, я не знаю, какой результат я получу обратно??? Пожалуйста, окажите любезную помощь!

3. @Peter — нет. SQL работает не так. Попробуйте пример из моего ответа. Единственная причина для выполнения подзапроса — это группировать по или агрегировать.

4. @Hogan прав. В вашем случае вам даже не нужен подзапрос. Я даже не смотрел на то, что вы на самом деле пытались сделать с помощью подзапроса, но просто увидел, что вам нужно исправить ваше предложение where . Лично я на самом деле предпочитаю объединения с использованием синтаксиса inner join customers on <condition> .

5. @squawknull — внутреннее соединение даст ему другие результаты, чем он хочет, я ожидаю.

Ответ №2:

Я не знаю, почему в вашей книге предложен подзапрос — Я бы сделал это следующим образом:

 Select Orders.OrderID, Customers.CompanyName 
  From Orders 
  left join Customers on Customers.CustomerID = Orders.CustomerID
  

Ответ №3:

Похоже, это должен быть коррелированный подзапрос

Выберите заказы.Идентификатор заказа,

    (Select Customers.CompanyName 
      From Customers 
      Where **Customers.CustomerID = Orders.CustomerID**) As Company Name
  

Из заказов

—, — Клиенты

Зачем вам снова нужны клиенты, когда внутренний коррелированный подзапрос возвращает имя клиента для каждого обрабатываемого заказа?

Настойчивость Management Studio в добавлении ПЕРЕКРЕСТНОГО СОЕДИНЕНИЯ является предупреждением о том, что вы делаете что-то странное. Пытаюсь запросить две таблицы: Клиент, Заказы без какого-либо условия соединения.

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

Где это уместно? Особенно, если вам нужно сгенерировать какой-то агрегат для внутреннего запроса.