如何在SQL中找到2方之间的第一条消息?

时间:2016-04-22 03:55:35

标签: sql sql-server

我有一个看起来像这样的消息表:

sender_id

我希望找到任意两个用户ID之间的第一条消息(recipient_id| id | sender_id | recipient_id | |-------------------|---------------| ... | 1 | 23 | 20 | | 2 | 11 | 5 | ... | 5 | 7 | 11 | 列中的ID)。因此上述样本的结果将是:

sender_id

起初我以为我可以通过recipient_idid的校验和进行分组,然后获取最小消息ID(1. cd / 2. sudo ls 3. cd Applications 4. sudo ls 5. cd Xcode.app 6. cd Contents/MacOS 7. ls 8. ./Xcode 9. sudo ./Xcode ),但因为校验和因顺序而异输入,返回第一个消息(简介)和第一个回复。是否存在校验和的替代方案,其中输入的顺序无关紧要?

或许有更好的方法来达成解决方案。

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:4)

您可以使用ROW_NUMBER

ONLINE DEMO

WITH CTE AS(
    SELECT *,
        ROW_NUMBER() OVER(
            PARTITION BY 
                CASE WHEN sender_id < recipient_id THEN sender_id ELSE recipient_id END,
                CASE WHEN sender_id > recipient_id THEN sender_id ELSE recipient_id END
            ORDER BY id
        ) AS rn
    FROM messages
)
SELECT
    id, sender_id, recipient_id
FROM CTE 
WHERE rn = 1
ORDER BY id

您需要使用较小的ID进行分区,然后使用CASE表达式进行更大的分区。

答案 1 :(得分:1)

; WITH CTE(ID,SENDER_ID, RECIEPENT_ID) AS
(
SELECT 1,23,20  UNION
SELECT 2,11,5   UNION
SELECT 3,20,23  UNION
SELECT 4,23,20  UNION
SELECT 5,7 ,11
)
SELECT *, ROW_NUMBER() OVER (PARTITION BY ABS(SENDER_ID - RECIEPENT_ID) ORDER BY ID) RN  FROM CTE 

从此使用RN = 1

答案 2 :(得分:1)

CREATE TABLE messages
(
    id int,
    sender_id int,
    recipient_id int
)

INSERT INTO messages
VALUES
    (1,23,20), 
    (2,11,5),
    (3,20,23),
    (4,23,20),
    (5,7,11)


SELECT 
    p.participant_1,
    p.participant_2,
    MIN(p.id)
FROM
(
    SELECT 
        id,
        participant_1 = sender_id,
        participant_2 = recipient_id
    FROM  messages a
    WHERE sender_id <= recipient_id
    UNION ALL
    SELECT 
        id,
        participant_1 = recipient_id,
        participant_2 = sender_id
    FROM  messages a
    WHERE sender_id > recipient_id
) p
GROUP BY p.participant_1,
         p.participant_2

答案 3 :(得分:0)

由于发件人和收件人都是整数标识符,如何以特定(例如升序)顺序连接它们?例如:

SELECT
  CONCAT(CAST(MIN(sender_id, recipient_id) AS CHAR),
         '-',
         CAST(MAX(sender_id, recipient_id) AS CHAR)) AS pair,
  MIN(id) AS id
FROM messages
GROUP BY pair

通过这种方式,无论哪个是发件人/收件人,我们都可以保证首先获得较低的数字,然后获得较高的数字。

请注意,如果您需要所请求的输出,则只需将messages表加入id上面的seqstring.raw表即可获得确切的行。