MySQl GROUP BY和ORDER BY没有做我想要的

时间:2010-08-12 10:39:00

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

我想在对结果进行分组之前对结果进行排序,但我似乎无法完成它。

我有这个问题:

SELECT DISTINCT
 product.id,
 product_number_value.att_value AS product_number,
 color_number_value.option_code AS color_number,
 size_value.option_code AS size_code,
 size_value.option_position AS size_position
FROM
 product
INNER JOIN product_attribute_relational AS product_number_relational ON product_number_relational.product_id = product.id
INNER JOIN product_att_varchar AS product_number_value ON product_number_relational.product_att_id = product_number_value.product_att_id
INNER JOIN product_attribute_relational AS color_number_relational ON color_number_relational.product_id = product.id
INNER JOIN product_att_select AS color_number_select ON color_number_relational.product_att_id = color_number_select.product_att_id
INNER JOIN attribute_option_value AS color_number_value ON color_number_select.att_value = color_number_value.option_id
INNER JOIN product_attribute_relational AS size_relational ON product.id = size_relational.product_id
INNER JOIN product_att_select AS size_select ON size_relational.product_att_id = size_select.product_att_id
INNER JOIN attribute_option_value AS size_value ON size_select.att_value = size_value.option_id
WHERE
 product_number_relational.att_id = 1 AND
 color_number_relational.att_id = 2 AND
 size_relational.att_id = 3 AND
 product.id IN (365, 366, 367, 368, 369, 371, 372, 373, 374)
ORDER BY
 product.id ASC

结果如下表所示:

id  product_number  color_number  size_code  size_position
365 F23740   311    S   24
366 F23740   311    M   25
367 F23740   311    L   26
368 F23740   311    XL   27
369 F23740   311    XS   23
371 F23745   213    S   24
372 F23745   213    M   25
373 F23745   213    L   26
374 F23745   213    XL   27

如果我按product_number分组,color_number我得到id 365 和371 但我希望得到id 369 和371,因为我希望在对它们进行分组之前按size_position对结果进行第一次排序。

我真的不知道如何完成这件事?!??中 有人可以帮帮我吗?

谢谢!

3 个答案:

答案 0 :(得分:2)

这是在分组查询中使用非分组列的问题。一般来说,这是要避免的。一些数据库引擎阻止你这样做,因为它没有逻辑意义 - 如果我想要一个组的product.id,但是哪一个是数据库引擎应该选择,因为单个组有多个选项?

ORDER BY仅用于在使用GROUP BY时处理聚合或分组列,但我不确定您是否可以轻松聚合。您正在寻找组中MIN(size_position)行的product.id.我认为为每个组隔离这一行的子查询可能是唯一的方法;我想不出一个简单的方法来解决这个问题。

修改

我在这些情况下的直觉总是分两步完成。我不喜欢嵌套子查询的巨大笨重查询,只是因为我觉得它们不可读。你对规范化的模式有一个很长的查询,所以我不打算在这里分解查询,我可能会犯错误。

查询1会将product_number,color_number和MIN(size_position)(按product_number,color_number分组)推送到临时表中。

然后,查询2将检索临时表中每个product_number,color_number,size_position的product_id。这样,您可以直接对最小尺寸位置进行连接。

在许多情况下,使用临时表的负面表现是过分夸大的(并非所有情况,但肯定是我在过去10年中在交易应用程序中进行的99%的查询)。

还有另一种可能涉及子查询自连接的可能性,但是如果模式如此严格规范化,我认为实现起来并不是特别有利。

答案 1 :(得分:1)

如果按product_number,color_number分组,则为列id返回的值是不确定的(因为它们对于每个product_number,color_number对都不相同)。有关详细说明,请参阅here

所以,你说“我想在对结果进行分组之前对结果进行排序”,你能说出为什么要对它们进行分组吗?你究竟想从中获得什么。

编辑:评论后:

SELECT DISTINCT

 product_number_value.att_value AS product_number,
 color_number_value.option_code AS color_number,
 min(size_value.option_position) AS sizePosition
from ...

group by product_number, color_number order by sizePosition

您将拥有product_number,但不是id。

答案 2 :(得分:0)

尝试按两列排序:

... ORDER BY product.id, size_position ASC

它将首先按id排序,然后按size_position排序。