我目前正在尝试实现搜索引擎功能,尝试有效地从3个表中返回信息。用法是数字搜索,无法使用自由文本,因此我不会尝试针对此方案进行优化。
使用的表格如下:
Companies hasMany Products
Products hasMany Prices
问题如下:
我想为符合任何指定标准的每家公司退回最便宜的单品(这可能是产品或价格的标准)
我的解决方案如下:
SELECT * FROM (
SELECT Company.id, Company.name AS CompanyName, Product.name, Product.quantity, Price.price
FROM Product
LEFT JOIN Price ON Product.id=Price.product_id
LEFT JOIN Company ON Product.company_id=Company.id
/* EXAMPLE CONDITIONS */
WHERE Price.price > 10 AND Product.quantity > 4
ORDER BY Price.price
) AS tmp_table
GROUP BY tmp_table.id
ORDER BY tmp_table.price;
问题:这种子查询方法是否是实现此解决方案的最有效方法?
执行时间从1毫秒到140毫秒不等,共有3家公司,每家公司有3个产品,每个产品都有3个价格,所以如果要达到数百个,可能会变得混乱。
创建了一个SQL小提琴答案 0 :(得分:1)
此查询依赖于MySQL的“功能”,具体记录 无法正常工作。也就是说,您假设外部group by
中的额外列来自第一行,而documentation明确指出:
MySQL扩展了GROUP BY的使用,以便选择列表可以引用 未在GROUP BY子句中命名的非聚合列。这意味着 前面的查询在MySQL中是合法的。您可以使用此功能 通过避免不必要的列排序来获得更好的性能 分组。但是,这主要适用于每个中的所有值 GROUP BY中未命名的非聚合列对于每个列都是相同的 组。服务器可以自由选择每个组中的任何值,所以 除非它们相同,否则所选值不确定。
我不推荐您使用的方法。
由于您使用的是group by
,因此可以使用group_concat()
/ substring_index()
方法执行此操作:
SELECT c.id, c.name AS CompanyName, Product.name,
substring_index(group_concat(p.name order by pr.price, p.product_id), ',', 1) as price,
substring_index(group_concat(p.quantity order by pr.price, p.product_id), ',', 1) as price,
MIN(pr.price) as price
FROM Product p LEFT JOIN
Price pr
ON p.id = pr.product_id LEFT JOIN
Company c
ON p.company_id = c.id
WHERE pr.price > 10 AND p.quantity > 4
GROUP BY c.id, c.name
ORDER BY pr.price;