2014-11-06 59 views
0

我最初希望看到每個供應商與每個客戶(間接通過分銷商)完成的總美元業務的細目,我試圖不使用Inner Join Syntax並使用下面查詢這個目的:瞭解子查詢

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寫這查詢。我的老師提供了這個解決方案,但我真的無法理解這個邏輯,因爲我從來沒有遇到過子查詢。

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。因此,儘管您可以用on 1=1cross join表示爲inner join,但cross join是SQL語言的一部分,而不是黑客。

類似地,from子句中的括號可以使邏輯更難遵循。顯式子查詢更容易閱讀。