这让我感到沮丧,我已经搜索了一段时间。
id int(11)
target_id int(11)
text text latin1_swedish_ci
ip_address varchar(20) latin1_swedish_ci
created_by_user_id int(11)
created_date datetime
数据示例:
id target_id ip_address created_by_user_id text created_date
1 113 192.168.0.1 1 test1 2014-08-24 12:32:01
1 113 192.168.0.1 1 test2 2014-08-24 13:32:01
1 1 192.168.0.1 113 test3 2014-08-21 13:32:01
1 1 192.168.0.1 113 test4 2014-08-22 13:32:01
如何选择最新结果,并按target_id分组?我已经尝试了以下SQL语句来正确分组,但它没有带来最新的结果。
SELECT
*
FROM
`fq_message`
GROUP BY
target_id
ORDER BY
id DESC
返回:
1 113 192.168.0.1 1 test1 2014-08-24 12:32:01
1 1 192.168.0.1 113 test3 2014-08-21 13:32:01
我想实现
1 113 192.168.0.1 1 test2 2014-08-24 13:32:01
1 1 192.168.0.1 113 test4 2014-08-22 13:32:01
答案 0 :(得分:3)
MySQL允许您编写正式不是SQL的查询。例如,以下查询可能在MySQL中有效,或者可能不在。一个理智的数据库肯定会拒绝它:
select *
from (
select *
from fq_message
order by
created_date desc
) SubQueryAlias
group by
target_id
这告诉MySQL在分组之前进行排序,如你所知。但这不是真正的SQL。 SQL标准说子查询集和表是无序的。所有其他数据库都会拒绝内部查询,因为它会强制执行无关紧要的排序顺序。
该查询还会选择*
,但target_id
上的群组。 MySQL将获取它遇到的第一个值,如果它遵循子查询排序,则是每个目标的最新值。但不能保证它会这样做。 MySQL如何处理这些事情甚至可以根据MySQL版本进行更改。
更好的方法是编写需要MySQL做正确事情的SQL。其中一种方法是使用每个目标的最新日期集合进行过滤连接:
select msg.*
from fq_message msg
join (
select target_id
, max(created_date) as max_date_for_this_target
from fq_message
group by
target_id
) filter
on msg.target_id = filter.target_id
and msg.created_date = filter.max_date_for_this_target
join
是inner join
,只会返回on
子句找到匹配项的行。结果是过滤掉了没有目标最新日期的消息。
有关更多方法和示例,请参阅greatest-n-per-group标记。
答案 1 :(得分:0)
试试他的代码:
SELECT
ID,
target_id,
ID_ADDRESS,
CREATED_BY_USER_ID,
(SELECT TEXT FROM [YOUR_TABLE_NAME] WHERE ID = TMP.ID AND TARGET_ID = TMP.TARGET_ID AND ID_ADDRESS = TMP.ID_ADDRESS AND CREATED_BY_USER_ID = TMP.CREATED_BY_USER_ID AND CREATED_DATE = TMP.CREATED_DATE),
CREATED_DATE
FROM
(
SELECT
ID,
target_id,
ID_ADDRESS,
CREATED_BY_USER_ID,
MAX(CREATED_DATE) AS CREATED_DATE
FROM
/* Instead of this from, use from [your table] */
(
SELECT 1 ID, 113 TARGET_ID, '192.168.0.1' ID_ADDRESS, 1 CREATED_BY_USER_ID, 'test1' TEXT, TO_DATE('2014-08-24 12:32:01', 'YYYY-MM-DD HH24:MI:SS') CREATED_DATE FROM DUAL UNION
SELECT 1 , 113 , '192.168.0.1' , 1 , 'test2' , TO_DATE('2014-08-24 13:32:01', 'YYYY-MM-DD HH24:MI:SS') FROM DUAL UNION
SELECT 1 , 1 , '192.168.0.1' , 113 , 'test3' , TO_DATE('2014-08-21 13:32:01', 'YYYY-MM-DD HH24:MI:SS') FROM DUAL UNION
SELECT 1 , 1 , '192.168.0.1' , 113 , 'test4' , TO_DATE('2014-08-22 13:32:01', 'YYYY-MM-DD HH24:MI:SS') FROM DUAL
)
GROUP BY ID, target_id, ID_ADDRESS, CREATED_BY_USER_ID
) TMP
ORDER BY ID, CREATED_DATE DESC
<强>结果:强>
1 113 192.168.0.1 1 8/24/2014 1:32:01 PM
1 1 192.168.0.1 113 8/22/2014 1:32:01 PM
在Oracle中测试