2016-08-12 3 views
1

У меня есть этот запрос:Выберите все данные из другой таблицы, даже если соответствующее значение из другой таблицы NULL

SELECT city.CITY_NAME, 
     SUM(case when c.CUSTOMER_ID=o.CUSTOMER_ID and o.ORDER_ID=od.ORDER_ID 
       then od.TOTAL_AMT_PER_ITEM 
       else 0 end) AS TOTAL_AMT_PER_ITEM 
FROM [ORDER] o 
INNER JOIN ORDER_DETAILS od 
    ON o.ORDER_ID = od.ORDER_ID 
INNER JOIN CUSTOMER c 
    ON o.CUSTOMER_ID = c.CUSTOMER_ID 
INNER JOIN CUSTOMER_ADDRESS ca 
    ON ca.CUSTOMER_ID = c.CUSTOMER_ID 
INNER JOIN CITY city 
    ON ca.CITY_ID = city.CITY_ID 
GROUP BY city.CITY_NAME 

Я новичок в SQL SERVER. Этот запрос отображает только CITY_NAME, который имеет соответствующее значение TOTAL_AMT_PER_ITEM. Мне нужно отображать все CITY_NAMEs в базе данных, даже если их соответствующее значение равно NULL. Какая работа для этого? Кто-нибудь может мне помочь? Благодаря!

+3

Вы должны [** LEFT JOIN **] (http://www.w3schools.com/sql/sql_join_left.asp) вместо 'ВНУТРЕННЕГО JOIN' –

+0

мне просто нужно, чтобы заменить все внутренние соединения с ЛЕВЫМ JOIN и ? –

+1

И вам не нужен оператор case в вашем SUM. Вы заботитесь об этом в своих объединениях. – scsimon

ответ

1
SELECT 
    city.CITY_NAME, 
    SUM(od.TOTAL_AMT_PER_ITEM) AS TOTAL_AMT_PER_ITEM 
FROM 
    CUSTOMER c 
INNER JOIN 
    CUSTOMER_ADDRESS ca 
    ON ca.CUSTOMER_ID = c.CUSTOMER_ID 
INNER JOIN 
    CITY city 
    ON ca.CITY_ID = city.CITY_ID 
LEFT JOIN 
    [ORDER] o 
    ON o.CUSTOMER_ID = c.CUSTOMER_ID 
LEFT JOIN 
    ORDER_DETAILS 
    ON o.ORDER_ID = od.ORDER_ID 
GROUP BY city.CITY_NAME 
2

Я могу изменить порядок присоединений, возможно, помощь.

  • Вы начинаете с CITY, потому что является источником для GROUP BY и попытаться увидеть, если есть какие-либо CUSTOMER_ADDRESS.
    • Я думаю, если у вас новый магазин, у вас может быть 0 клиентов.
  • Тогда INNER JOIN потому, что направление не могу существовать в одиночку, они принадлежат к клиенту
  • Тогда LEFT JOIN, потому что снова CUSTOMER может или не может иметь [ORDERS].
  • Тогда INNER JOIN, потому что каждый [ORDERS] имеет [ORDER DETAILS]
  • Наконец вы SUM(od.TOTAL_AMT_PER_ITEM) из последних JOIN таблицы, это может получить некоторые NULL's так что вам нужно включить COALESCE

    SELECT city.CITY_NAME, 
         COALESCE(SUM(od.TOTAL_AMT_PER_ITEM) , 0) as TOTAL_AMT_PER_ITEM 
    FROM [CITY] 
    LEFT JOIN [CUSTOMER_ADDRESS] ca 
         ON ca.CITY_ID = [CITY].CITY_ID 
    INNER JOIN CUSTOMER c 
        ON ca.CUSTOMER_ID = c.CUSTOMER_ID 
    LEFT JOIN [ORDER] o 
        ON o.CUSTOMER_ID = c.CUSTOMER_ID 
    INNER JOIN ORDER_DETAILS od 
        ON o.ORDER_ID = od.ORDER_ID  
    GROUP BY [CITY].CITY_NAME 
    

Кстати, вы должны изменить название таблицу [Order] - [Orders], потому что заказ является зарезервированным словом и может вызвать проблемы.

В общем, я предпочитаю использовать множественное имя для таблиц, потому что является объектом сохранения кратного типа

  • ГОРОД вместо CITY
  • КЛИЕНТОВ Intead ЗАКАЗЧИКА
  • order_details уже во множественном числе, так что попробуйте сохранить консистенцию.
+0

Более информативный, чем мой. +1 хороший сэр – scsimon

Смежные вопросы