我有一张名为' 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
如何解决这个问题的任何帮助或见解!
答案 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