2016-04-22 8 views
1

私はこのようになりますメッセージテーブルを持っている:SQLで2人のパーティー間の最初のメッセージを見つけるには?

| id | sender_id | recipient_id | 
|-------------------|---------------| ... 
| 1 | 23  |  20  | 
| 2 | 11  |  5  | ... 
| 3 | 20  |  23  | 
| 4 | 23  |  20  | ... 
| 5 | 7  |  11  | 

私は任意の2つのユーザID(sender_idrecipient_id列内のID)との間に最初のメッセージを見つけることを願っています。したがって、上記の試料についての結果は次のようになります

| id | sender_id | recipient_id | 
|-------------------|---------------| ... 
| 1 | 23  |  20  | 
| 2 | 11  |  5  | ... 
| 5 | 7  |  11  | 

最初Iはsender_idrecipient_idのチェックサムによってグループIは考えていた、そして次に分のメッセージID(id)を取るが、チェックサムに依存して異なるため最初のメッセージ(イントロ)と最初の応答の両方を返す入力の順序。入力の順序が関係のないチェックサムの代替手段がありますか?

解決策が見つかるかもしれません。

ご迷惑をおかけして申し訳ありません。

答えて

4

あなたはROW_NUMBERを使用することができ、この使用FROM:

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と使用して、次に大きい一つのパーティションを必要としますa CASE発現。

+1

私はあなたの答えが好きです。私はCTEテーブルを使う必要があるとは思わない。 URパーティションのロジックでグループ化し、minを使用します。SENDER_ID THEN SENDER_ID ELSE recipient_id ENDをrecipient_id WHEN EX \t \tため、 \t \t \t分(ID) を \t \t \t PARTICIPANT1 = CASEをFROM SELECTメッセージ \t基\t CASE SENDER_ID recipient_id THEN sender_id ELSE recipient_id END – dfdsfdsfsdf

+0

@KMC、それは良いことです。私はあなたがそれについて別の答えを投稿することをお勧めします。 –

+0

これはあなたのソリューションに基づいています。すべてのあなたのクレジット。 lol – dfdsfdsfsdf

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

+1

abs(sender_id - receipient_id)があなたのパーティションである場合、(10-5)は(5-10)と(15-10)と同じパーティションにあり、間違っています。 – dfdsfdsfsdf

+0

ええ、真実ですが、答えは与えられたデータサンプルのためだけでした – TharunRaja

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 

我々が最初に下の数、そして第二に、関係なく、1は、送信者/受信者となっている高い数値を得ることが保証されているこの方法です。

要求した出力が必要な場合は、ちょうど正確な行を取得するために、idの上にあるmessagesテーブルを参加させるだけです。

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 
関連する問題