SQL: GROUP BY vs. DISTINCT. What is the best one in this situation? SQL: GROUP BY与DISTINCT。在这种情况下哪个更好?
SQL: GROUP BY vs. DISTINCT. What is the best one in this situation? SQL: GROUP BY与DISTINCT。在这种情况下哪个更好?
我对数据库不太了解,对于我在MySql数据库上执行的查询,我有以下疑问。\n我有如下查询:\n
SELECT CD.id AS id, CD.commodity_name_en AS commodity_name_en FROM MarketDetails AS MD INNER JOIN MarketDetails_CommodityDetails AS MD_CD ON MD.id = MD_CD.market_details_id INNER JOIN CommodityDetails AS CD on MD_CD.commodity_details_id = CD.id WHERE MD.localization_id = 1
\n它返回的结果是(代表一些市场上的商品列表):\n
id commodity_name_en ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1 Rice-Asia 2 Apple banana 3 Avocado 4 Red onion 5 White onion 6 Green Beans 7 Bell pepper 8 Carrot 9 Tomatoes 10 Irish potatoes 11 Maize 1 Rice-Asia 3 Avocado 5 White onion 8 Carrot 11 Maize 2 Apple banana 7 Bell pepper 9 Tomatoes 10 Irish potatoes 1 Rice-Asia
\n如您所见,这些商品可能会出现多次(因为特定商品可能在多个市场上销售)。\n我想修改我的查询,使得每个商品只出现一次(因为最终我想要所有可能商品的列表,而不重复)。\n所以我知道可以这样做:\n
SELECT CD.id AS id, CD.commodity_name_en AS commodity_name_en FROM MarketDetails AS MD INNER JOIN MarketDetails_CommodityDetails AS MD_CD ON MD.id = MD_CD.market_details_id INNER JOIN CommodityDetails AS CD on MD_CD.commodity_details_id = CD.id WHERE MD.localization_id = 1 GROUP BY id
\n我通过ID进行分组,但也可以通过名称进行分组(结果相同)。\n我的疑问是:我可以使用DISTINCT语句来获得相同的效果吗?\n根据这里的阅读,似乎这可能是一个解决方案:https://www.tutorialspoint.com/sql/sql-distinct-keyword.htm\n所以我也尝试了这个解决方案,似乎返回了相同的结果:\n
SELECT DISTINCT CD.id AS id, CD.commodity_name_en AS commodity_name_en FROM MarketDetails AS MD INNER JOIN MarketDetails_CommodityDetails AS MD_CD ON MD.id = MD_CD.market_details_id INNER JOIN CommodityDetails AS CD on MD_CD.commodity_details_id = CD.id WHERE MD.localization_id = 1
\n那么DISTINCT和GROUP BY解决方案之间的确切区别是什么?在我这种情况下,哪个更聪明?\n谢谢
在这种情况下,问题的原因是在查询商品时使用了JOIN操作来获取市场信息,然后再从结果集中去除重复项。这样做的效率较低,因为在去除重复项之前必须对所有数据进行排序。
为了解决这个问题,可以使用两种方法。第一种方法是在WHERE子句中使用EXISTS或IN子句,从商品表中选择存在于特定市场的商品。第二种方法是使用子查询,先选择特定市场的市场ID,然后再选择对应的商品ID。
为什么这样能节省时间呢?首先,我们编写SQL查询时,应该考虑可读性和可维护性。我们应该首先考虑这一点。如果你想选择商品,就选择商品,而不是商品与市场的连接。至于速度方面:聚合和去除重复项是相当慢的过程。所有数据必须首先进行排序才能完成这一过程。这对于大型表格来说可能是一个相当大的任务(对于小型表格来说,这不会有太大的差异)。
无论如何,只有在遇到性能问题时才考虑加快查询速度。不要为了以为这样可能会欺骗数据库管理系统生成更好的执行计划而使查询变得晦涩难懂。
在这个问题中,原始查询使用了DISTINCT关键字来返回唯一的行。然而,使用GROUP BY关键字也可以实现相同的效果。所以问题是,在这种情况下,使用哪个方法更好?
通过观察提供的查询,我们可以看到它使用了多个表进行连接,并且包含了一些过滤条件。根据这个查询的逻辑,我们可以看出,它的目的是返回满足过滤条件的唯一行。因此,使用DISTINCT和GROUP BY都可以实现相同的结果。
然而,根据给出的建议,我们可以使用一个更有效的方法来实现相同的目标。这个方法是使用EXISTS子查询来代替DISTINCT或GROUP BY。通过使用EXISTS,我们可以避免对整个结果集进行聚合操作,从而节省了计算资源。
具体实现的查询如下:
SELECT CD.id, CD.commodity_name_en
FROM CommodityDetails CD
WHERE EXISTS (SELECT 1
FROM MarketDetails MD INNER JOIN
MarketDetails_CommodityDetails MD_CD
ON MD.id = MD_CD.market_details_id
WHERE MD_CD.commodity_details_id = CD.id AND
MD.localization_id = 1
);
这个查询的逻辑是,首先从CommodityDetails表中选择满足条件的行,并且对于每一行,检查是否存在满足特定条件的MarketDetails行。如果存在,那么就返回该行的id和commodity_name_en列。
需要注意的是,我们在查询中删除了对列的别名的指定。默认的别名对于CD.id
是id
,因此没有必要显式指定(除非您喜欢键入和冗长的查询)。
关于您具体的问题,评论中已经回答了--DISTINCT和GROUP BY应该具有非常相似的性能。因此,在这种情况下,选择使用哪个方法取决于个人偏好和代码风格。