Mysql唯一列对,如A,B或B,A,其中C更高

时间:2017-07-23 07:26:05

标签: mysqli

我有这张桌子

    id|id_user_send|id_user_receive|date
    -------------------------------------
    0 |    1       |     2         |  2017-04-06
    0 |    2       |     1         |  2017-04-07
    0 |    1       |     4         |  2017-04-07
    0 |    1       |     4         |  2017-04-08
    0 |    4       |     1         |  2017-04-09
    0 |    1       |     2         |  2017-04-10

我只想要唯一的一对id_user_send,id_user_receive或id_user_receive,id_user_send,其中日期更高。

我没看到如何获得这个白衣组或选择不同我尝试数字关闭联合但不工作。你能给我一个我想要理解的方式而不仅仅是答案,请非常感谢你帮助。

编辑:对我来说,情侣1,4和4,1是相同的,我希望更高的日期

1 个答案:

答案 0 :(得分:0)

这个查询将帮助您从包含A,B或B,A的所有行中获取最大值C.

这里使用的列是..

  • A =发件人( id_user_send
  • B =接收方( id_user_receive
  • C =天( date

Explanation:

  • 查询包含UNION个2个查询
  • First Query中,表T1T2是包含发件人,接收者,串联字符串(发件人,收件人)及其最大值(日)的行。 WHERE子句将串联的字符串(sr)与相同字符串的反向匹配,这将获得发送方和接收方组合相同的所有行,即(1-4和4-1)。使用CASE..WHEN..END,我们可以获得具有最大日期的行。
  • Second Query涵盖corner scenarios行,即发送者和接收者之间单向交互的行以及相同的发送者和接收者。

样本数据准备

CREATE TABLE stack(sender int, receiver int, day date);

-- rows with sender:receiver as 1-4 or 4-1 (TWO_WAY INTERACTION)
INSERT INTO stack VALUES(1, 4, TO_DATE('2017-04-06', 'yyyy-mm-dd'));
INSERT INTO stack VALUES(1, 4, TO_DATE('2017-04-08', 'yyyy-mm-dd'));

INSERT INTO stack VALUES(4, 1, TO_DATE('2017-02-06', 'yyyy-mm-dd'));
INSERT INTO stack VALUES(4, 1, TO_DATE('2017-01-06', 'yyyy-mm-dd'));

-- rows with sender:receiver as 1-1 or 2-1 (TWO_WAY INTERACTION)
INSERT INTO stack VALUES(1, 2, TO_DATE('2017-06-06', 'yyyy-mm-dd'));
INSERT INTO stack VALUES(1, 2, TO_DATE('2017-04-06', 'yyyy-mm-dd'));

INSERT INTO stack VALUES(2, 1, TO_DATE('2017-09-06', 'yyyy-mm-dd'));
INSERT INTO stack VALUES(2, 1, TO_DATE('2017-01-06', 'yyyy-mm-dd'));

-- rows with sender:receiver as 3-6 (CORNER SCENARIO : ONE_WAY INTERACTION)
INSERT INTO stack VALUES(3, 6, TO_DATE('2017-09-06', 'yyyy-mm-dd'));
INSERT INTO stack VALUES(3, 6, TO_DATE('2017-01-06', 'yyyy-mm-dd'));

-- rows with sender:receiver as 7-7 (CORNER SCENARIO : SELF INTERACTION)
INSERT INTO stack VALUES(7, 7, TO_DATE('2017-09-06', 'yyyy-mm-dd'));
INSERT INTO stack VALUES(7, 7, TO_DATE('2017-01-06', 'yyyy-mm-dd'));

<强> Sample Data View enter image description here

<强> Query

    SELECT DISTINCT 
        CASE
           WHEN T1.maxDay >= T2.maxDay THEN T1.sender ELSE T2.sender
        END as sender,
        CASE
           WHEN T1.maxDay >= T2.maxDay THEN T1.receiver ELSE T2.receiver
        END as receiver,
        CASE
           WHEN T1.maxDay >= T2.maxDay THEN T1.maxDay ELSE T2.maxDay
        END as maxDay
    FROM
        (SELECT sender, receiver, (sender || ',' || receiver) AS sr, MAX(day) AS maxDay
        FROM stack
        GROUP BY sender, receiver, (sender || ',' || receiver)) T1,
        (SELECT sender, receiver, (sender || ',' || receiver) AS sr, MAX(day) AS maxDay
        FROM stack
        GROUP BY sender, receiver, (sender || ',' || receiver)) T2
    WHERE T1.sr = REVERSE(T2.sr)
UNION
    SELECT T1.sender, T1.receiver, T1.maxday
    FROM
        (SELECT sender, receiver, (sender || ',' || receiver) AS sr, MAX(day) AS maxDay
        FROM stack
        GROUP BY sender, receiver, (sender || ',' || receiver)) T1
    WHERE T1.sr NOT IN 
        (SELECT DISTINCT (REVERSE(sender || ',' || receiver))
        FROM stack)

<强> Result enter image description here

如果您需要更多的查询说明,请与我们联系。

我还提供了SQL Fiddle,您可以通过逐个执行查询来理解它。

http://sqlfiddle.com/#!4/2d6f7/3/0