使用来自多个表的计算字段优化查询

时间:2014-10-01 13:23:53

标签: mysql sql

我有四张桌子

store[store_id(pk),name]
itemsA(item_id(pk),store_id,name)
itemB(item_id(pk),store_id,name)
itemC(item_id(pk),store_id,name)

我想要一个查询来检索商店和他拥有的商品数量。类似的东西:

select s.store_id ,s.name,count() as numberOfItems from store limit 100

通过以下限制实现该目标的最佳查询是什么: 无法在db中创建函数 无法创建视图 我只能在db上运行查询 感谢

3 个答案:

答案 0 :(得分:1)

此查询不会显示没有项目的商店。如果这是一项要求,则必须稍加调整。

SELECT s.store_id, COUNT(*)
FROM Store s
JOIN ItemA a ON a.store_id = s.store_id
JOIN ItemB b ON b.store_id = s.store_id
JOIN ItemC c ON c.store_id = s.store_id
GROUP BY s.store_id

一个简单的修改,还包括0项商店:

SELECT s.store_id, COUNT(a.store_id) + COUNT(b.store_id) + COUNT(c.store_id)
FROM Store s
LEFT JOIN ItemA a ON a.store_id = s.store_id
LEFT JOIN ItemB b ON b.store_id = s.store_id
LEFT JOIN ItemC c ON c.store_id = s.store_id
GROUP BY s.store_id

答案 1 :(得分:1)

我建议使用相关子查询来执行此操作:

select s.store_id, s.name,
       ((select count(*) from itemsA a where a.store_id = s.store_id) +
        (select count(*) from itemsB b where b.store_id = s.store_id) +
        (select count(*) from itemsC c where c.store_id = s.store_id)
       ) as numberOfItems
from store s
limit 100;

然后,您希望在每个项目表中都有一个索引:itemsA(stored_id)itemsB(store_id)itemsC(store_id)

优化的原因是因为它只需要计算limit选择的任意100个商店的值。并且,可以直接从索引进行计算。其他方法需要对所有商店进行计算。

注意:通常在使用limit时,您需要order by子句。

答案 2 :(得分:0)

如果我理解正确

DECLARE @store TABLE (store_id INT, name NVARCHAR(100))
DECLARE @itemsA TABLE (item_id INT,store_id INT, name NVARCHAR(100))
DECLARE @itemsB TABLE (item_id INT,store_id INT, name NVARCHAR(100))
DECLARE @itemsC TABLE (item_id INT,store_id INT, name NVARCHAR(100))

INSERT INTO @store VALUES (1,'Store1')
INSERT INTO @store VALUES (2,'Store2')

INSERT INTO @itemsA VALUES (1,1,'itemsA_item1')
INSERT INTO @itemsA VALUES (2,1,'itemsA_item2')
INSERT INTO @itemsA VALUES (3,1,'itemsA_item3')

INSERT INTO @itemsB VALUES (1,2,'itemsB_item1')
INSERT INTO @itemsB VALUES (2,2,'itemsB_item2')
INSERT INTO @itemsB VALUES (3,2,'itemsB_item3')
INSERT INTO @itemsB VALUES (4,1,'itemsB_item4')


INSERT INTO @itemsC VALUES (1,3,'itemsC_item1')
INSERT INTO @itemsC VALUES (2,3,'itemsC_item2')
INSERT INTO @itemsC VALUES (3,2,'itemsC_item3')

SELECT TOP 100 store_id, SUM(HasItems) AS TotalItems FROM
(
    SELECT store_id, COUNT(name) AS HasItems FROM @itemsA GROUP BY store_id
    UNION
    SELECT store_id, COUNT(name) AS HasItems FROM @itemsB GROUP BY store_id
    UNION
    SELECT store_id, COUNT(name) AS HasItems FROM @itemsC GROUP BY store_id
) AS StoreItems
GROUP BY store_id