【问题标题】:comparison of joins连接比较
【发布时间】:2015-06-15 08:38:04
【问题描述】:

假设我有一个名为 sales 的表,其中包含 itemid、storeid、sale 和 date 列

然后我有一个名为 storeregion 的表,其中包含 storeid 和 region 列。如果我想获得特定日期范围内某个地区的销售额:

select region, sum(sale)

from sales s
inner join storeregion sr on s.storeid=sr.storeid

where date between 'whatever' and 'whatever'

group by region

所以我得到这样的结果:

东|500

西|400

好的,很酷。现在,我还有一个名为 itemcategory 的表,其中包含 itemid 和 category 列。我想看看每个区域每个类别的销售额。我可以做这样的事情。

select sr.region, ic.category, sum(sale)

from sales s
inner join storeregion sr on s.storeid=sr.storeid
inner join itemcategory ic on s.itemid=ic.itemid

where date between 'whatever' and 'whatever'

group by sr.region
group by ic.category

所以我得到这样的结果:

东方|玩具|100

东方|书籍|200

东部|奥运会|200

西部|玩具|300

西部|游戏|100

现在我真正想做的是找到一个地区的一个类别的销售额占该地区总销售额的 50% 以上的地方。因此,根据我在第一个查询中的示例,我得到了结果:

西|400

在第二个查询中我得到了结果:

西部|玩具|300

占该地区总销售额的 50% 以上。

我想写一个只给我结果的查询

西部|玩具|300

因为它占该地区销售额的 50% 以上。有什么想法吗?

【问题讨论】:

  • 首先,您应该选择您正在使用的数据库,并适当地标记问题:MySQL 还是 SQL Server?
  • 对不起,SQL Server。固定。

标签: sql sql-server


【解决方案1】:

您可以使用 子查询 来做到这一点。将您的查询加入到按地区计算总数的子查询中,条件是销售额 > 总数的 50%:

select sr.region, ic.category, sum(sale) sales

from sales s
inner join storeregion sr on s.storeid=sr.storeid
inner join itemcategory ic on s.itemid=ic.itemid
INNER JOIN 
(

    select region, sum(sale) sales

    from sales s
    inner join storeregion sr on s.storeid=sr.storeid

    where date between 'whatever' and 'whatever'

    group by region

) st ON sr.region = st.region
where date between 'whatever' and 'whatever'

group by sr.region,ic.category, st.sales
having sum(sale) > st.sales * 0.50

请注意,条件需要在 HAVING 子句中,因为它适用于组总数,而不是记录值。

【讨论】:

  • D 斯坦利,感谢您的回答;但是,我收到错误消息,即“have”子句中的“sales”无效,因为它们不包含在聚合函数或 GROUP BY 子句中。有什么建议吗?
  • 我将 st.sales 添加到 group by,这将起作用,因为每个区域的总区域销售额将相同。
【解决方案2】:

你应该使用窗口函数来做到这一点:

select rc.*
from (select sr.region, ic.category, sum(sale) as catsale,
             sum(sum(sale)) over (partition by region) as regsale
      from sales s inner join
           storeregion sr
           on s.storeid = sr.storeid inner join
           itemcategory ic
           on s.itemid = ic.itemid
      where date between 'whatever' and 'whatever'
      group by sr.region, ic.category
     ) rc
where catsale >= 0.5 * regsale;

一般来说,窗口函数不仅可以缩短查询时间,而且它们的性能也优于使用多个连接和聚合的等效查询。

【讨论】:

    【解决方案3】:

    您需要执行以下操作:

    select a.region, a.category, a.sales from (
     your first query
    ) as a join (
    your second query
    ) as b on join both
    having b.sales > a.sales / 2
    

    【讨论】:

      猜你喜欢
      • 2010-12-20
      • 2013-11-24
      • 1970-01-01
      • 1970-01-01
      • 2015-12-22
      • 2010-09-09
      • 2015-10-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多