mysql select 通过返回具有优先顺序的行进行分组

mysql select with group by returning rows with a preference order

我有以下mysql查询结果:

+----+------------+-------------+
| id |   title    |     lang    | 
+----+------------+--------------
| 1  | ola1       |  1          | 
| 1  | hello1     |  2          |
| 1  | bonjour1   |  3          |
| 2  | ola2       |  1          | 
| 2  | bonjour2   |  3          |
| 3  | hello3     |  2          |
| 4  | bonjour4   |  3          |
+----+------------+-------------+

我想要的是 group_by 按 id 查询,它为每个 id 提供标题以及 lang 字段的优先顺序。示例:

语言偏好顺序 1、2、3 的结果:

+----+------------+-------------+
| id |   title    |     lang    | 
+----+------------+--------------
| 1  | ola1       |  1          | 
| 2  | ola2       |  1          | 
| 3  | hello3     |  2          |
| 4  | bonjour4   |  3          |
+----+------------+-------------+

语言偏好顺序 3、2、1 的结果:

+----+------------+-------------+
| id |   title    |     lang    | 
+----+------------+--------------
| 1  | bonjour1   |  3          | 
| 2  | bonjour2   |  3          | 
| 3  | hello3     |  2          |
| 4  | bonjour4   |  3          |
+----+------------+-------------+

谢谢!

这是 MySQL 中未定义的功能。非聚合列中显示的值是不确定的。 read more here (MySQL Documentation).

(标准SQL不允许在使用GROUP BY时包含非聚合列,我想这是原因之一)。

根据你对你想做的事情的描述,你应该SELECT所有行都包含你要查找的语言

SELECT * FROM your_table WHERE lang = 1

不可能,或者我的 SQL 技能无法在一个查询中执行它。对于这些问题,我总是最终使用一个临时模板和两个 SQL 命令:

(假设你的table叫Table1,临时的table应该叫tempTable)

SELECT Table1.id, Min(Table1.lang) AS Min_Of_lang INTO tempTable FROM Table1 GROUP BY Table1.id ORDER BY Table1.id;
SELECT Table1.* FROM tempTable INNER JOIN Table1 ON (tempTable.MinOflang = Table1.lang) AND (tempTable.id = Table1.id);

第一个命令创建一个新的 table(如果存在则覆盖当前的 table)。第二个命令使用第一个 table 生成所需的结果集。

要将第一个所需结果 table 更改为第二个,请在第一个查询中使用 Max 而不是 min。

其他人可能有比我的更优雅的解决方案。此外,可以添加一个额外的 SQL 语句来删除临时 table.