每列值选择限制1?


11

可以说我有下表

-----------------------------
| user_id   | comment       |
-----------------------------
| 2         | thats cool    |
| 2         | awesome       |
| 3         | i hate this   |
| 3         | okay          |
| 6         | this is weird |
| 6         | hello?        |
| 6         | what is it    |
| 9         | how are you   |
| 16        | too slow      |
| 16        | yes           |
| 17        | alrighty      |
-----------------------------

如何选择每一行user_id?所以我的结果是:

-----------------------------
| user_id   | comment       |
-----------------------------
| 2         | thats cool    |
| 3         | i hate this   |
| 6         | this is weird |
| 9         | how are you   |
| 16        | too slow      |
| 17        | alrighty      |
-----------------------------

一个有效的查询是否有可能?还是需要子选择?是否可以以某种方式DISTINCT在单个列上使用?

Answers:


9

GROUP BY就是用的。获取一行(每组)。在这种情况下,它会显示所有不同user_id数值和列的其余部分,你可以(必须)使用聚合功能,如MIN()MAX()AVG()SUM()因为你将每组有一个以上的值,只有一个可以显示。

SELECT
    user_id
  , MIN(comment) AS comment  -- it will show the first in alphabetical order  
                             -- you could also use MAX()
FROM
    tableX
GROUP BY
    user_id ;

MySQL还允许使用以下非常规解决方案,该解决方案将为每个用户返回一个(或多或少随机)注释:

SELECT
    user_id
  , comment
FROM
    tableX
GROUP BY
    user_id ;

如果ONLY_FULL_GROUP_BY启用了(限制器)模式,则最后一个查询将不起作用,但会引发错误。在最近发布的5.7版本中,此模式是默认模式ANY_VALUE(),并提供了一个新功能。有关更多详细信息,请参见MySQL处理GROUP BY页面。现在可以编写查询:

SELECT
    user_id
  , ANY_VALUE(comment) AS comment
FROM
    tableX
GROUP BY
    user_id ;

请注意,无论使用“非正统”版本还是使用最新ANY_VALUE()功能,如果我们在SELECT列表中添加更多列,则不能保证它们的值来自同一行,而不能来自同一组中的一行。选择它们的方式并非完全随机,这取决于执行计划和所使用的索引。


是否还有其他方法指定要为user_id提取哪一行?有什么方法可以指定ORDER BY吗?
杰克·威尔逊

除了MINMAX
ypercubeᵀᴹ

1
那就更复杂了。看到另一个问题:MySQL查询-如何获取最新的人口统计信息?
ypercubeᵀᴹ

2
您还可以在SO网站的[greatest-n-per-group]标签下找到大量类似的问题。
ypercubeᵀᴹ

1
如果您在SELECT列表中添加所有其他列,那么@ T.BrianJones在“非正统”查询中是什么意思?这是第一个,它们可能不在同一行。它不是完全随机的,但是值可以来自不同的行(来自同一组)。
ypercubeᵀᴹ
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.