MySQL按特定字段分组结果

时间:2017-08-09 21:11:31

标签: mysql

我有一张名为' 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

我想要一个SELECT语句,每个location_id选择一行并按日期排序。

由于ONLY_FULL_GROUP_BY要求(以及与其他数据库类似的严格标准),我的具体问题是创建一个可以与MySQL 5.7.1及更高版本一起使用的语句

SELECT id, location_id , date FROM test GROUP BY location_id  ORDER BY date

正常工作,但MySQL数据库升级的那天它无效。

SELECT id, location_id , date FROM test GROUP BY location_id, id, date  ORDER BY date

有效但不起作用,它会返回所有结果。

我想要的是获取上面第一个SELECT查询的结果,但是使用了有效的SQL,它具有面向未来的能力,它将返回:

id     | location_id | date
1      | 1           | 2017-01-02
3      | 2           | 2017-01-04

如何解决这个问题的任何帮助或见解!

2 个答案:

答案 0 :(得分:1)

根据您提供的示例数据,您希望这样做:

SELECT  MIN(id) AS ID,
        Location_ID,
        MIN(Date) AS Date
FROM    test
GROUP BY Location_ID
ORDER BY Date 

我们已将聚合函数应用于id和date,因此您只需将location_id保留在group by中。并且在相同的数据上,您似乎只选择最小的id - 日期。这可能是一个误导性假设,所以让我知道

修改

根据我们的聊天情况,我想出了以下内容:

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

我所做的是复制MSSQL's ROW_NUMBER()的方法并在location_id上进行分区。为了更好地理解该函数,请阅读here

给出以下示例数据:

1 | 1 | 2017-01-02
2 | 1 | 2017-01-03
3 | 2 | 2017-01-04
4 | 1 | 2017-01-05

视图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

“分区”基于我们选择的@id,然后是我们的订单。如果我们将订单更改为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

因此,根据我们订购日期的方式,我们可以选择最新日期或第一日期 - 您必须在php中处理asc / desc。

最后,我们返回的数据将与id一致,因此上面的查询将输出:

id | location_id | date
1  | 1           | 2017-01-02
3  | 2           | 2017-01-04

请告诉我这是否更接近您所寻找的内容!

答案 1 :(得分:0)

SELECT DISTINCT能为您提供所需吗?

SELECT DISTINCT id, location_id , date FROM test GROUP BY location_id, id, date  ORDER BY date