2016-11-14 72 views
0

假设我有这三个表:SQL策略以获取最大

enter image description here

我想,所有的产品,它的PRODUCT_ID和客户端bougth它大部分的时间(最大的产品的客户端)。

我解决了它这样的:

SELECT 
product_id AS product, 
(SELECT TOP 1 client_id FROM Bill_Item, Bill 
    WHERE Bill_Item.product_id = p.product_id 
    and Bill_Item.bill_id = Bill.bill_id 
GROUP BY 
    client_id 
ORDER BY 
    COUNT(*) DESC 
) AS client 
FROM Product p 

你知道更好的办法?

+0

? –

+0

SQL Server 2012 –

+1

不确定它是否会优化查询,但最好使用'JOIN',这样您的查询就可以更改为'FROM Bill_Item INNER JOIN Bill Bill_Item.product_id = p.product_id 和Bill_Item.bill_id = Bill.bill_id'您可以使用SHOWPLAN来检查执行计划。 –

回答

1

我打算提交与@Squirrell几乎一样的东西,只用公用表表达式[CTE]而不是派生表。所以我不会重复,但有一些关于您的查询的学习要点。首先是IMPLICIT JOINSFROM Bill_Item, Bill真的很容易产生意想不到的后果(许多问题之一:Queries that implicit SQL joins can't do?)接下来对于计算列,您实际上可以在OUTER APPLYCROSS APPLY中执行此操作,这是非常有用的技术。

SELECT * 
FROM 
    Product p 
    OUTER APPLY (SELECT TOP 1 b.client_id 
      FROM 
       Bill_Item bi 
       INNER JOIN Bill b 
       ON bi.bill_id = b.bill_id 
      WHERE 
       bi.product_id = p.product_id 
      GROUP BY 
       b.client_id 
      ORDER BY 
       COUNT(*) DESC) c 

,并说明squirell的回答怎么还包括从未被出售所有你需要做的是加入的产品和LEFT JOIN要产品有:

所以你可以按如下方式重新写你的方法其他表格:

;WITH cte AS (
    SELECT 
     p.product_id 
     ,b.client_id 
     ,ROW_NUMBER() OVER (PARTITION BY p.product_id ORDER BY COUNT(*) DESC) as RowNumber 
    FROM 
     Product p 
     LEFT JOIN Bill_Item bi 
     ON p.product_id = bi.product_id 
     LEFT JOIN Bill b 
     ON bi.bill_id = b.bill_id 
    GROUP BY 
     p.product_id 
     ,b.client_id 
) 

SELECT * 
FROM 
    cte 
WHERE 
    RowNumber = 1 

其中一些有用的技术。

  • CTE
  • 适用(外&十字)
  • 窗口功能
  • 您正在使用什么版本的SQL
2

内部查询会给你排名。外部查询会给你购买最多的产品的客户

SELECT * 
(
    SELECT i.product_id, b.client_id, 
      r = row_number() over (partition by i.product_id 
             order by count(*) desc) 
    FROM Bill b 
      INNER JOIN Bill_Item i ON b.bill_id = i.bill_id 
    GROUP BY i.product_id, b.client_id 
) d 
WHERE r = 1 
1

松鼠的答案不会返回从未销售的产品。如果你想包括,那么你的做法是好的,但我会写查询为:

SELECT product_id as product, 
     (SELECT TOP 1 b.client_id 
     FROM Bill_Item bi JOIN 
      Bill b 
      ON bi.bill_id = b.bill_id 
     WHERE Bill_Item.product_id = p.product_id 
     GROUP BY client_id 
     ORDER BY COUNT(*) DESC 
     ) as client 
FROM Product p; 

你也可以使用这种利用APPLY,但相关子查询也可以。

请注意正确使用显式JOIN语法。