Корректен ли этот SQL-запрос? Я использую ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ

#sql #join

#sql #Присоединиться

Вопрос:

Используя тип соединения, верните имя, фамилию, номер заказа записей клиентов, созданных после 1 ноября 2010 года. Включайте номера заказов в 3-й столбец, только если этот клиент разместил какие-либо заказы.

    SELECT c.firstname,
          c.lastname,
          o.ordernumber 
     FROM Customers c
LEFT JOIN Orders o ON c.customerid = o.customerid
    WHERE o.orderdate > '2010-01-01'
      AND o.ordernumber IS NOT NULL
  

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

1. Будьте осторожны, 1 ноября 2010 года не ‘2010-01-01’, как написано выше.

2. Вы сказали: customer records created after Nov 1, 2010 но в вашем запросе вы проверяете Orders.OrderDate столбец (также для другой даты, как аккуратно заметил Брайан). Действительно ли этот столбец связан с созданием записей клиентов? Или что на самом деле означает «создание записей клиентов»?

Ответ №1:

Это то же самое, что и внутреннее соединение. Пример:

 SELECT c.firstname,
c.lastname,
o.ordernumber FROM   Customers c
Inner JOIN Orders o
ON     c.customerid = o.customerid
where o. orderdate > '01-01-2010'
  

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

Как указывает @Bryan, возможно, вы захотите посмотреть на преобразование вашей даты в соответствии с вашим форматом. По этой ссылке показано, как преобразовать varchar в datetime в зависимости от формата.

Ответ №2:

LEFT OUTER JOIN Результатом будет строка для каждой строки в Customer таблице. Это можно лучше увидеть в вики-статье. Использование INNER JOIN вернет строки только для клиентов, у которых есть соответствующие заказы.

Ответ №3:

Без тестирования этого, я думаю, вам не понадобится «and ordernumber is not null».

В итоге вы получите:

 FirstName| LastName| OrderNumber
John       Smith     1
John       Smith     2
Joe        Bloggs    NULL     <-- Joe has no orders
  

Вы говорите: «Покажите мне всех и их приказы. Если у кого-то нет заказов, покажите их в любом случае»

Ответ №4:

Это неверно, условие WHERE примет значение false, если заказа нет, поэтому клиенты без заказов не будут включены (я предполагаю, что вам нужны все клиенты, поскольку вы пишете «Включать номера заказов в 3-й столбец, только если этот клиент разместил какие-либо заказы.», поэтому использование INNER JOIN, как предлагают другие, было бы неправильным).

Вы, вероятно, хотите просто удалить o.ordernumber IS NOT NULL условие.

Ответ №5:

Если под «записями клиентов» вы действительно подразумеваете «заказы клиентов», то, возможно, ваш запрос должен выглядеть следующим образом:

    SELECT c.firstname,
          c.lastname,
          o.ordernumber 
     FROM Customers c
LEFT JOIN Orders o ON c.customerid = o.customerid
      AND o.orderdate > '2010-01-01'
                  /* or '2010-11-01', if you want Nov 1, 2010 */
  

Это выведет всех клиентов. Третий столбец будет содержать либо NULL, либо номер заказа.

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