2014-11-06 67 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子句中的括号可以使逻辑更难遵循。显式子查询更容易阅读。