MYSQL Max日期组由两列组成

时间:2015-11-06 09:43:18

标签: mysql group-by max

我希望在我的表中获取发送方和接收方之间的最新创建日期,其中发送方或接收方= 002,然后按发送方和接收方进行分组。最后,从002的角度通知成员是发送者还是接收者。

这只是一个示例数据。

id    sender    |    receiver    |       create_date
1      001              002           2015-10-13 10:30:01  
2      003              002           2015-11-06 15:30:59
3      001              002           2015-11-02 05:30:01
4      001              002           2015-11-03 11:08:22
5      002              004           2015-10-20 12:15:36
6      002              004           2015-11-03 17:35:10
7      002              005           2015-09-01 06:02:20
8      002              001           2015-11-06 15:10:32 

结果应如下所示

id    |    member    |    type    |       create_date
2           003          sender       2015-11-06 15:30:59
6           004         receiver      2015-11-03 17:35:10
7           005         receiver      2015-09-01 06:02:20
8           001         receiver      2015-11-06 15:10:32

到目前为止,我已经尝试过:

1)

SELECT
    id,
    IF(sender <> '002', sender, receiver) AS member, 
    IF(sender <> '002', 'sender', 'receiver') AS type, 
    MAX(create_date) AS max_date
FROM
    table
WHERE
    sender = '002' OR receiver = '002'
GROUP BY
    member

这是我最后得到的结果。

id    |    member    |    type    |       create_date
1           001          sender       2015-11-06 15:10:32
2           003          sender       2015-11-06 15:30:59
5           004         receiver      2015-11-03 17:35:10
7           005         receiver      2015-09-01 06:02:20

我很难获得最新的当前行,但create_date没有问题。

2)我也尝试过使用内连接。

SELECT
    *
FROM
    table a
INNER JOIN
(
    SELECT
        id,
        MAX(create_date) as max_date
    FROM
        table
    WHERE
        sender = '002' OR receiver = '002'        
) b ON b.max_date = a.create_date

这适用于仅检索最新的行记录。但是,如果我需要使用最新的create_date检索行,但是需要通过发送方和接收方分组?

3 个答案:

答案 0 :(得分:2)

您可以使用案例

在一个选择中执行此操作
select 
case when sender='002' then receiver else sender end as member, -- # knowing that either sender or receiver are 002, take the other.
case when sender='002' then 'receiver' else 'sender' end as type,
max(date)
from table
where sender = '002' or receiver = '002'
group by 1,2

答案 1 :(得分:1)

这是一种非常无效的方法,但它会取得正确的结果:

SELECT id, t.member, COALESCE(IF(sender<>2,'sender',NULL),'receiver') type, t.create_date 
FROM a
JOIN (
 SELECT COALESCE(IF(sender<>2,sender,NULL),receiver) member, MAX(create_date) create_date 
 FROM a GROUP BY member
) t on ((a.sender=t.member or a.receiver=t.member) AND a.create_date=t.create_date)
WHERE a.sender='002' OR a.receiver='002';

内部子选择将为每个相关成员找到最新的create_date,外部选择将找到该特定行。

答案 2 :(得分:1)

可能使用子查询来获取包含日期的成员和类型列表,然后从中获取最大值: -

SELECT member, type, MAX(create_date)
FROM
(
    SELECT sender AS member, 'sender' AS type, create_date
    FROM table
    WHERE receiver = '002'
    UNION
    SELECT receiver AS member, 'receiver' AS type, create_date
    FROM table
    WHERE sender = '002'
) sub0
GROUP BY member, type

ID是一个小问题。如果需要,那么它需要根据成员/类型/创建日期加入到表中以获取它,或者使用GROUP_CONCAT: -

SELECT SUBSTRING_INDEX(GROUP_CONCAT(id ORDER BY create_date DESC), ',', 1), 
        member, 
        type, 
        MAX(create_date)
FROM
(
    SELECT id, sender AS member, 'sender' AS type, create_date
    FROM table
    WHERE receiver = '002'
    UNION
    SELECT id, receiver AS member, 'receiver' AS type, create_date
    FROM table
    WHERE sender = '002'
) sub0
GROUP BY member, type