mysql group by问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql group by问题相关的知识,希望对你有一定的参考价值。
在表中我有这四个字段SID,CONTACT_ID,CONTACT_NAME,CONTACT_TIME ,我想排除掉CONTACT_NAME中相同的,并且根据CONTACT_TIME降序排序。
SELECT * FROM `recent_contacts` group by `CONTACT_NAME` ORDER BY `CONTACT_TIME` desc我的语句是这么写的,但是group by合并后为什么时间保存的是最早的时间点,而不是最新的时间点。这个该怎办
SELECT t.* FROM (
SELECT * FROM recent_contacts ORDER BY CONTACT_TIME desc
) t ORDER BY t.CONTACT_NAME
通过EXPLAIN 可以看到是先执行的group by 然后才是 order by 。。。,先排下序,然后在分组,这么写效率很低,数据量不超过100W级别就可以用,超过了必须建立包含查询的字段的一个复合索引
追问这样子排序后,我想把重复的合并起来,值显示时间最新的哪个怎么显示呢
追答sql写错了
SELECT * FROM recent_contacts ORDER BY CONTACT_TIME desc
) t group BY t.CONTACT_NAME 参考技术A CONTACT_NAME相同其他值也是相同么,不同的话你想怎么取呢,比如
1,2,3,5
2,4,3,6
这样 CONTACT_NAME 相同,对于其他3列值你想怎么处理呢追问
ID跟NAME是相同的,就时间不同,我想吧ID跟NAME合并了,但是TIME里显示的是最新的哪个时间。用GROUP BY显示的是第一次的时间。
SQL:MySQL 中的 GROUP BY 问题
【中文标题】SQL:MySQL 中的 GROUP BY 问题【英文标题】:SQL : a GROUP BY issue in MySQL 【发布时间】:2012-12-02 05:47:04 【问题描述】:这是数据库表
╔════╦═════════════╦══════════════════╦═══════╗
║ id ║ customer_id ║ last_seen ║ param ║
╠════╬═════════════╬══════════════════╬═══════╣
║ 1 ║ 12345 ║ 2012-08-01 12:00 ║ 1 ║
║ 2 ║ 22345 ║ 2012-08-01 12:00 ║ 1 ║
║ 3 ║ 32345 ║ 2012-08-01 12:00 ║ 1 ║
║ 4 ║ 42345 ║ 2012-08-01 12:00 ║ 1 ║
║ 5 ║ 52345 ║ 2012-08-01 12:00 ║ 1 ║
║ 6 ║ 12345 ║ 2012-09-01 12:00 ║ 2 ║
║ 7 ║ 12345 ║ 2012-10-01 12:00 ║ 3 ║
╚════╩═════════════╩══════════════════╩═══════╝
其中id
是自动增量主键。
我想要实现的是获取每个customer_id
的最后一条记录。预期结果:
╔════╦═════════════╦══════════════════╦═══════╗
║ id ║ customer_id ║ last_seen ║ param ║
╠════╬═════════════╬══════════════════╬═══════╣
║ 2 ║ 22345 ║ 2012-08-01 12:00 ║ 1 ║
║ 3 ║ 32345 ║ 2012-08-01 12:00 ║ 1 ║
║ 4 ║ 42345 ║ 2012-08-01 12:00 ║ 1 ║
║ 5 ║ 52345 ║ 2012-08-01 12:00 ║ 1 ║
║ 7 ║ 12345 ║ 2012-10-01 12:00 ║ 3 ║
╚════╩═════════════╩══════════════════╩═══════╝
我试过这个 SQL,但它返回的结果不正确:
SELECT customer_id, param, last_seen
FROM `my_table`
GROUP BY customer_id
ORDER BY last_seen DESC
我在这里错过了什么?
UPDATE:表结构(DESC my_table
的输出)
+--------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| customer_id | varchar(8) | NO | | NULL | |
| last_seen | datetime | NO | | NULL | |
| param | int(11) | NO | | NULL | |
+--------------+--------------+------+-----+---------+----------------+
【问题讨论】:
在 ANSI SQL 中,您不能在group by
查询中选择 ugrouped 字段,因为它的值未定义。某种程度上 MySQL 允许它。
能否请您检查记录id 6
的last_seen
值是否正确?
@KuyaJohn 这是一个错字,现已更正
哇设计编辑 :),谢谢@saharsh shah
【参考方案1】:
这是SQLFiddle demo
在 MySQL 中你可以这样做:
select ID,CUSTOMER_ID,LAST_SEEN,PARAM from
(
select t.*,
if(@i=customer_id,0,1) isLast,
@i:=customer_id
from `my_table` t,(select @i:=0) t1
order by customer_id,last_seen desc
) t2 where isLAst=1
【讨论】:
在引用我的数据库架构时,t
、t1
和 t2
是什么?我无法运行查询。
我已根据使用 my_table
更改了查询。 t,t1,t2 是别名
终于设法运行您的查询。但是,PHP 内存已耗尽,phpmyadmin 停止响应。使用 MySQL 5.1【参考方案2】:
子查询背后的想法是它为每个Customer_ID
分别获取最新的last_seen
值。如果必须满足条件,则子查询的结果将与原始表连接:CustomerID
和 日期 必须相互匹配。
SELECT a.*
FROM Customer a
INNER JOIN
(
SELECT Customer_ID, MAX(last_seen) maxDate
FROM Customer
GROUP BY Customer_ID
) b ON a.Customer_ID = b.Customer_ID AND
a.last_seen = b.maxDate
ORDER BY a.ID
SQLFiddle Demo
后续问题:请问记录id6
的last_seen
值是否正确?
【讨论】:
错字,现已修复记录 id 6。我的 MySQL 服务器在执行此查询时挂起并停止响应。 你有多少条记录?你也有索引Customer_ID
?
我在 id
列上有索引,但现在在 Customer_ID
列上。我有 ~220,000 条记录
你的服务器挂起(但实际上没有)的原因是因为它正在执行FULL TABLE SCAN
您应该在(customer_ID, last_seen)
上添加索引以获得更好的性能。以上是关于mysql group by问题的主要内容,如果未能解决你的问题,请参考以下文章