[英]MySQL grouping results by specific field
I have a table named 'test' like so: 我有一个名为“ test”的表,如下所示:
id | location_id | date
1 | 1 | 2017-01-02
2 | 1 | 2017-01-03
3 | 2 | 2017-01-04
4 | 1 | 2017-01-05
I would like a SELECT statement that selects one row per location_id and ordered by date. 我想要一个SELECT语句,该语句为每个location_id选择一行并按日期排序。
My specific problem is creating a statement that'll work with MySQL 5.7.1 and later, due to the ONLY_FULL_GROUP_BY requirements (and similar strict standards with other DBs) 由于ONLY_FULL_GROUP_BY的要求(以及其他数据库的类似严格标准),我的特定问题是创建一条适用于MySQL 5.7.1及更高版本的语句。
SELECT id, location_id , date FROM test GROUP BY location_id ORDER BY date
Works, but it's invalid the day the MySQL db is upgraded. 可以,但是在升级MySQL数据库的那天无效。
SELECT id, location_id , date FROM test GROUP BY location_id, id, date ORDER BY date
Is valid, but does not work, it returns all the results. 有效,但不起作用,它将返回所有结果。
What I would like is to obtain the results of the first SELECT query above, but with valid SQL that's future-proof, which returns: 我想要的是获得上面第一个SELECT查询的结果,但是要使用有效的SQL,它可以满足未来的需求,它返回:
id | location_id | date
1 | 1 | 2017-01-02
3 | 2 | 2017-01-04
Any help or insight on how to get around this appreciated! 任何帮助或见解如何解决这个赞赏!
Based on the sample data you've provided you want to do this: 根据您提供的样本数据,您要执行以下操作:
SELECT MIN(id) AS ID,
Location_ID,
MIN(Date) AS Date
FROM test
GROUP BY Location_ID
ORDER BY Date
We've applied aggregate functions to id and date so you only need to keep location_id in the group by. 我们已将汇总函数应用于id和date,因此您只需要在分组依据中保留location_id。 and on the same data you seem to only choose the smallest id - date.
并且在相同的数据上,您似乎只选择了最小的ID-日期。 This is probably a mislead assumption so let me know
这可能是一个误导性的假设,所以让我知道
EDIT 编辑
Based on our chat, I've come up with the following: 根据我们的聊天,我提出了以下建议:
SELECT id, location_id, Date
FROM (
SELECT t1.*,
@cur := IF(location_id = @id, @cur+1, 1) AS RowNumber,
@id := location_id AS IdCache
FROM docs t1
CROSS JOIN (
SELECT @id:=(SELECT MIN(location_id) FROM docs), @cur:=0) AS init
ORDER BY t1.location_id, date
) PartitionedData
WHERE RowNumber = 1
order by location_id
What I've done is replicate the methodology of MSSQL's ROW_NUMBER()
and partitioned on location_id
. 我所做的是复制
MSSQL's ROW_NUMBER()
并在location_id
分区。 To get a better understanding of that function read up on it here 为了更好地了解该功能,请在此处阅读
Given the following example data: 给定以下示例数据:
1 | 1 | 2017-01-02
2 | 1 | 2017-01-03
3 | 2 | 2017-01-04
4 | 1 | 2017-01-05
The view, PartitionedData
, will return the following data set: 视图
PartitionedData
将返回以下数据集:
id | location_id | date | RowNumber | IdCache
1 | 1 | 2017-01-02 | 1 | 1
2 | 1 | 2017-01-03 | 2 | 1
4 | 1 | 2017-01-05 | 3 | 1
3 | 2 | 2017-01-04 | 1 | 2
The "Partitioning" is based on what we are choosing as the @id and then our order by. “分区”基于我们选择的@id,然后根据我们的排序。 If we change the order by to be
t1.location_id, date desc
then our dataset would be: 如果我们将顺序更改为
t1.location_id, date desc
则我们的数据集将为:
id | location_id | date | RowNumber | IdCache
4 | 1 | 2017-01-05 | 1 | 1
2 | 1 | 2017-01-03 | 2 | 1
1 | 1 | 2017-01-02 | 3 | 1
3 | 2 | 2017-01-04 | 1 | 2
So depending on how we order the date we can select the latest or first date - you'll have to handle the asc/desc in the php. 因此,根据我们订购日期的方式,我们可以选择最新的日期或第一次的日期-您必须在php中处理asc / desc。
Finally, our returned data will coincide with the id so the above query will output: 最后,我们返回的数据将与ID一致,因此上述查询将输出:
id | location_id | date
1 | 1 | 2017-01-02
3 | 2 | 2017-01-04
Let me know if this is closer to what you are looking for! 让我知道这是否更接近您要寻找的东西!
SELECT DISTINCT是否满足您的需求?
SELECT DISTINCT id, location_id , date FROM test GROUP BY location_id, id, date ORDER BY date
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.