通过连接表数据进行排序的复杂SQL查询

时间:2013-05-08 21:10:20

标签: sql join group-by sql-order-by

以下是样本数据,尽可能简化:

Table: items (id / manufacturer)
1 / Microsoft
2 / Microsoft
3 / Microsoft
4 / ACME
5 / Microsoft

Table: order_rows (item_id / date)
1 / 2012-12-01
1 / 2013-01-01
2 / 2013-01-02
2 / 2013-01-03
3 / 2013-01-04
3 / 2013-01-05
3 / 2013-01-06

我想要一份微软列出的所有商品,按自2013-01-01以来的购买数量排序。

因此,Microsoft在order_rows中具有最多条目的日期> 2013-01-01将是第一个。自2013-01-01以来所有零购买的商品都位于底部(不包括在列表中)。

这可以通过单个查询完成吗?此外,这实在太贵了吗?

所需的输出将按以下方式订购: 3,2,1,5

2 个答案:

答案 0 :(得分:3)

您应该能够使用与此类似的内容加入表格,然后使用ORDER BY count(item_id) desc按照您想要的顺序获取数据:

select i.id, i.manufacturer
from items i
left join order_rows o
  on i.id = o.item_id
  and o.date > '2013-01-01'
where i.manufacturer  ='Microsoft'
group by i.id, i.manufacturer
order by count(o.item_id) desc;

请参阅SQL Fiddle with Demo

如果您只想要ID,则可以从SELECT和GROUP BY中删除manufacturer

select i.id
from items i
left join order_rows o
  on i.id = o.item_id
  and o.date > '2013-01-01'
where i.manufacturer  ='Microsoft'
group by i.id
order by count(o.item_id) desc;

请参阅SQL Fiddle with Demo

答案 1 :(得分:2)

如果order_rows表有大量行,则查询可能会对性能有所帮助。

SELECT b.id, b.`manufacturer`, a.cnt AS num_orders
  FROM
       (
       SELECT item_id, COUNT(*) AS cnt
         FROM order_rows
        WHERE item_id IN (SELECT id FROM items WHERE manufacturer = 'Microsoft')
          AND date >= '2013-01-01'
        GROUP BY item_id
       ) a
 RIGHT OUTER JOIN items b
    ON a.item_id = b.id
 WHERE b.`manufacturer` = 'Microsoft'
 ORDER BY IFNULL(a.cnt, 0) DESC

这将产生如下结果:

enter image description here

请参阅SQL Fiddle

上的在线演示