MySQL Using ORDER BY and GROUP BY together
我有一个表具有id价格类别的产品等...我试图从每个item_category中提取1个项目,这是最近的一个(在其自己的类别中具有最高的ID)。
这是代码,它从6个类别中获取6个项目,但它们是最旧的(ID最小)
1 2 3
| SELECT * from items WHERE item_category = '2' or item_category = '4' or
item_category = '12' or item_category = '13' or item_category = '14' or
item_category = '19' GROUP BY `item_category` ORDER BY `item_id` LIMIT 6 |
按ID排序在返回的6个项目的数组上执行,而在原始表格上没有。
我该如何取代最新的项目呢?
我认为最好的查询
1 2 3 4 5
| select *
from items
where item_category in ("2","4","12","13","14","19")
group by item_category
order by item_category DESC |
-
你为什么用GROUP BY?
-
您的查询可以像这样的SELECT * FROM items WHERE item_category IN('2', '4', '12', '13', '14' ,'19') ORDER BY item_id DESC LIMIT 6,其中ORDER BY item_id DESC表达式按行item_id按行的顺序排序
-
如果禁用ONLY_FULL_GROUP_BY,则对GROUP BY的标准SQL使用的MySQL扩展允许选择列表,HAVING条件或ORDER BY列表引用非聚合列,即使这些列在功能上不依赖于GROUP BY列。这导致MySQL接受前面的查询。在这种情况下,服务器可以自由选择每个组中的任何值,因此除非它们相同,否则所选的值是不确定的,这可能不是您想要的。此外,添加ORDER BY子句不会影响每个组中值的选择
-
可能只是SELECT item_category, MAX(item_Id) ... GROUP BY item_category。但是,当您尝试按所选内容的一列进行分组而不是被所有非聚合列强制分组时,我感到惊讶的是MySQL并没有出现问题。你不应该这样做
-
@apokryfos是MAX ITEM ID正确返回它们,所以我需要做的就是使用返回的数组来选择实际的项目,对吗?我对功能和其他复杂用途不是很熟悉......
-
@DenislavKaragiozov,来自@apokryfos的答案是正确的,应该写成答案。我写了,但希望他得到分数。您可以将*添加到SELECT,以便获得分组和排序以及完整项目详细信息:SELECT item_category, MAX(item_id) AS max_id, * FROM items WHERE item_category IN (...) GROUP BY item_category ORDER BY max_id
-
那么你也可以做SELECT * FROM items WHERE id IN (SELECT MAX(item_id) /* your original query */)
-
@davidethell @apokryfos SELECT item_category, MAX(item_id) AS max_id, * FROM items WHERE item_category IN ("2","4","12","13","14","19") GROUP BY item_category ORDER BY max_id虽然引发了错误...我不确定原始查询的哪一部分我需要放入/ *您的原始查询* /来自apokryfos回答
首先要指出的是,如果您不打算在分组中包含所有非聚合列,则应该训练自己不要使用group by。 例:
1 2 3
| SELECT col1 ,col2 FROM table GROUP BY col1 -- BAD
SELECT col1 ,col2 FROM table GROUP BY col1 ,col2 -- GOOD
SELECT col1 ,MAX(col2 ) FROM table GROUP BY col1 -- GOOD |
这是因为显而易见的问题是,您在列中不是唯一且不可预测的值,这些列在组中是唯一的,这是您所有问题的根源。
说过你应该这样做:
1 2 3
| SELECT item_category , MAX(item_id )
FROM items
WHERE item_category IN ('2','4','12','13','14','19') GROUP BY `item_category` |
请注意,没有必要限制,因为您只能有6个组,并且order by不再执行任何操作。
如果要获取相应的项目行,可以执行以下操作:
1 2 3 4 5 6 7 8
| SELECT *
FROM items
WHERE item_id IN (
SELECT MAX(item_id )
FROM items
WHERE item_category IN ('2','4','12','13','14','19')
GROUP BY item_category
); |
以下可能也有效:
1 2 3 4 5 6 7
| SELECT *
FROM items i JOIN (
SELECT i2 .item_category , MAX(i2 .item_id ) as max_item_id
FROM items i2
WHERE i2 .item_category IN ('2','4','12','13','14','19') GROUP BY
i2 .`item_category`
) max_ids ON i .item_id =max_ids .max_item_id ; |
-
感谢您的代码和时间! 对我来说最终的最终解决方案是在第一个SELECT中添加*并返回每个项目的每一列。 SELECT *,item_category,MAX(item_id)FROM items WHERE item_category IN('2','4','12','13','14','19')GROUP BY item_category
-
这样做时你需要非常小心。 您不一定要确保作为*的一部分返回的列与MAX(item_id)对应
-
是的,它们不是......所以实际的最终查询是 - SELECT *来自项目WHERE item_id IN(SELECT MAX(item_id)FROM items WHERE item_category IN('2','4','12','13 ','14','19')GROUP BY item_category)
-
更新了答案,以反映您实际执行的操作。 不确定连接是否优于select / in。 我怀疑他们的表现方式或多或少相同。
-
行动非常简单,IMO的差异可以忽略不计。 干得好!