2014-11-06 2 views
0

Я изначально хотел увидеть разбивку общего долларового бизнеса, который каждый поставщик сделал (косвенно через дистрибьютора) с каждым клиентом, где я пытаюсь не использовать Синтаксис внутреннего соединения, и использовал запрос ниже для этой цели:Понять подзапросы

select customers.cust_id, Vendors.vend_id, sum(quantity*item_price) as total_business from 
(((Vendors left outer join Products 
on Products.vend_id = Vendors.vend_id) 
left outer join OrderItems --No inner joins allowed 
on OrderItems.prod_id = Products.prod_id) 
left outer join Orders 
on Orders.order_num = OrderItems.order_num) 
left outer join Customers 
on Customers.cust_id = Orders.cust_id 
where Customers.cust_id is not null -- THE ONLY DIFFERENCE BETWEEN QUERY1 AND QUERY2 
group by Customers.cust_id, Vendors.vend_id 
order by total_business 

Теперь я пытаюсь увидеть результаты вывода запроса для всех комбинаций поставщика клиентов, в том числе тех комбинаций, в которых не было никакого дела транзакционного и я пытаюсь написать это с помощью одного SQL Запрос. Мой учитель предоставил это решение, но я, честно говоря, не могу понять логику вообще, поскольку я никогда не сталкивался с Sub-запросами.

select 
    customers.cust_id, 
    Vendors.vend_id, 
    sum(OrderItems.quantity*orderitems.item_price) 
    from 
     (
     customers 
     inner join 
     Vendors on 1 = 1 
    ) 
    left outer join --synthetic product using joins 
     (
     orders 
     join 
     orderitems on orders.order_num = OrderItems.order_num 
     join 
     Products on orderitems.prod_id = products.prod_id 
    ) on 
     Vendors.vend_id = Products.vend_id and 
     customers.cust_id = orders.cust_id 
group by customers.cust_id, vendors.vend_id 
order by customers.cust_id 

Большое спасибо

ответ

0

Я бы написать этот запрос, как:

select c.cust_id, v.vend_id, coalesce(cv.total, 0) 
fro Customers c cross join 
    Vendors v left outer join 
    (select o.cust_id, v.vend_id, sum(oi.quantity * oi.item_price) as total 
    from orders o join 
      orderitems oi 
      on o.order_num = oi.order_num join 
      Products p 
      on oi.prod_id = p.prod_id 
    group by o.cust_id, v.vend_id 
    ) cv 
    on cv.vend_id = v.vend_id and 
     cv.cust_id = c.cust_id 
order by c.cust_id; 

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

Последний шаг заключается в их объединении.

Ваш учитель должен поощрять вас использовать псевдонимы таблиц, в частности сокращения таблиц. Вам также следует поощрять использование надлежащего join. Итак, хотя вы можете выразить cross join как inner join с on 1=1, cross join является частью языка SQL, а не взлома.

Аналогично, круглые скобки в предложении from могут сделать логику сложнее следовать. Явные подзапросы легче читать.