2013-05-08 88 views
3

订购这里是样本数据,归结尽可能:复杂的SQL查询的连接表数据

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。

因此,无论哪个项目的order_rows中的条目数最多,其中date> 2013-01-01的条目将是第一个。自2013-01-01以来购买零次数的所有商品都位于底部(不排除在列表之外)。

这可能通过单个查询来完成吗?另外,这会太昂贵而不实用吗?

所需的输出将如下命令: 3,2,1,5

回答

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,那么你就可以删除的选择和分组的manufacturer BY:

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

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

+0

+1,先贴的回答为我工作,但我可能会尝试你的版本以及比较速度 – irregularexpressions 2013-05-09 17:39:04