2016-05-05 3 views
0

私は "チャット" SQLテーブルを読むのに少し助けが必要です。SQL SELECT - Chats

コラム:...取得する方法

Chat_ID - decimal(18, 0) primary key, inflexible-yes 

Sent_ID - decimal(18, 0) 

Receive_ID - decimal(18, 0) 

Time - datetime 

Message - nvarchar(MAX) 


Sent_ID| Receive_ID |  Time  |  Message 
-------+----------+------------------+----------------- 
    1 | 2  | 11/21/2015 10:00 | Hey! test 
-------+----------+------------------+----------------- 
    2 | 1  | 11/21/2015 10:50 | Hi! respond 
-------+----------+------------------+----------------- 
    1 | 2  | 11/21/2015 10:51 | respond 3 
-------+----------+------------------+----------------- 
    2 | 1  | 11/21/2015 11:05 | respond final 
-------+----------+------------------+----------------- 
    1 | 3  | 11/21/2015 11:51 | Message 1 
-------+----------+------------------+----------------- 
    3 | 1  | 11/21/2015 12:05 | Message 2 
-------+----------+------------------+----------------- 
    1 | 3  | 11/21/2015 12:16 | Message Final 
-------+----------+------------------+----------------- 
    4 | 1  | 11/21/2015 12:25 | New message 1 
-------+----------+------------------+----------------- 

Sent_ID| Receive_ID |  Time  |  Message 
-------+----------+------------------+----------------- 
    2 | 1  | 11/21/2015 11:05 | respond final 
-------+----------+------------------+----------------- 
    1 | 3  | 11/21/2015 12:16 | Message Final 
-------+----------+------------------+----------------- 
    4 | 1  | 11/21/2015 12:25 | New message 1 
-------+----------+------------------+----------------- 

あなたは、私が何か必要なことに注意してください(各ユーザに最後のメッセージを?):、MAX(時間) Sent_ID = 1 ..... Receive_ID = 1を簡略化するために、
:WHERE(Sent_ID = @ Receive_ID = @ Sent_IDまたは@ Receive_ID) = 1) は....

+0

を試してみてください? –

答えて

1

更新をありがとう:私は、それが送信または受信された場合は、関係なく、二人のユーザー間での最新のメッセージを取得したいことを今理解しています。そのような場合は、ROW_NUMBER使用することができます。

ONLINE DEMO

WITH Cte AS(
    SELECT *, 
     rn = ROW_NUMBER() OVER(
        PARTITION BY 
         CASE 
          WHEN Sent_ID > Receive_ID THEN Receive_ID 
          ELSE Sent_ID 
         END, 
         CASE 
          WHEN Sent_ID > Receive_ID THEN Sent_ID 
          ELSE Receive_ID 
         END 
        ORDER BY Time DESC 
       ) 
    FROM chats 
    WHERE 
     Sent_ID = 1 
     OR Receive_ID = 1 
) 
SELECT 
    Sent_ID, Receive_ID, Time, Message 
FROM Cte 
WHERE rn = 1 

を何上記のクエリを行うことは第一下部ID、およびより高いIDでチャットメッセージを分割することです。このようにして、異なるIDの組み合わせを使用するようにします。


まず、ユーザーが最後に送信したメッセージを取得する必要があります。そして、それは他のユーザのそれぞれからユーザによって受信された最後のメッセージにそれを返します。

SELECT c.* 
FROM chats c 
INNER JOIN (
    SELECT 
     Sent_ID, MAX(Time) AS MaxTime 
    FROM chats 
    WHERE Sent_ID = 1 
    GROUP BY Sent_ID 
) t 
    ON t.Sent_ID = c.Sent_ID 
    AND t.MaxTime = c.Time 

UNION ALL 

SELECT c.* 
FROM chats c 
INNER JOIN (
    SELECT 
     Sent_ID, MAX(Time) AS MaxTime 
    FROM chats 
    WHERE Receive_ID = 1 
    GROUP BY Sent_ID 
) t 
    ON t.Sent_ID = c.Sent_ID 
    AND t.MaxTime = c.Time 

ONLINE DEMO

+0

私はこれをデータベース上でテストします。しかし、あなたのオンラインデモが正しく動作していないのを見たとき。繰り返し列1と3 ...しかし、私はテストします... – Milan

+0

@ミラン、ああ、私はあなたの問題を誤解しました。私の更新された答えを見てください。 –

+0

あなたの答えをありがとう、私はテストします。 – Milan

0

問題は、行とでは、ユーザーIDとの間のSQLサーバの会話のように、ユニークされていない(1及び2)は、ユーザID(2,1)、SQLサーバの間の会話と同じではありませんそれを別のものとして見てください。

だから私のアドバイスは

create table Conversation (ConvoID int, FromID int, ToID int) 

insert into COnversation (ConvoID, FromID, ToID) 
values (1, 1, 2), 
     (1, 2, 1), 
     (2, 1, 3), 
     (2, 3, 1) 

のようなものをという名前の別のテーブルを作成するために、そしてあなたがあなたの「チャット」テーブルの上に会話テーブルに参加し、ConvoIDとmax日付でグループで行くことができます...のでだろうそれはユニークな

0

する二人のユーザー間でチャットを行うための唯一の方法であるDBMSは、使用している。この

select c.* from 

(select User1id,User2id,max(time) as newtime 
    from 
    (select 
     case when sent_id < receive_id then sent_id else receive_id 
    end as User1id, 
     case when sent_id > receive_id then sent_id else receive_id 
    end as User2id, 
    time 
    from chats where (Sent_ID = 1 or Receive_ID = 1) 
    ) temp 
    group by User1id,User2id 
)t1 
    inner join chats c on 
    t1.newtime = c.time