4

ユーザーのチャット メッセージを格納するテーブルがあります。すべてのメッセージがこのテーブルに記録されます。特定のユーザーのチャット時間を計算する必要があります。

ユーザーが x 回チャットし、x+10 回後にチャットを終了する可能性があるためです。X+20 時間後、ユーザーは再びチャットを開始します。したがって、x+10 から x+20 までの期間は考慮されません。

表の構造とサンプル データは次のとおりです。異なる色は、同じユーザーの 2 つのチャット セッションを表します。663 と 662 の間には 1 時間以上の差があることがわかるので、そのようなセッションは結果セットから除外する必要があります。最終結果は 2.33 分です。

ここに画像の説明を入力

declare @messagetime1 as datetime
declare @messagetime2 as datetime
select @messagetime1=messagetime from tbl_chatMessages where ID=662
select @messagetime2=messagetime from tbl_chatMessages where ID=659
print datediff(second,@messagetime2,@messagetime1)
   Result --- 97 seconds

declare @messagetime3 as datetime
declare @messagetime4 as datetime
select @messagetime3=messagetime from tbl_chatMessages where ID=668
select @messagetime4=messagetime from tbl_chatMessages where ID=663
print datediff(second,@messagetime4,@messagetime3)
   Result -- 43 seconds

チャットの時間を計算するソリューションを提案してください。これは私が考えることができるロジックの 1 つです。解決策を共有してください

4

5 に答える 5

0

このクエリを使用できます ( here ):

DECLARE @Results TABLE(
  RowNum INT NOT NULL,
  senderID INT NOT NULL DEFAULT(80),
  recipientID INT NOT NULL DEFAULT(79),
    PRIMARY KEY(RowNum,senderID,recipientID),
  messageTime DATETIME NOT NULL
);
INSERT INTO @Results(RowNum,senderID,recipientID,messageTime)
SELECT  ROW_NUMBER() OVER(PARTITION BY senderID,recipientID ORDER BY messageTime, ID) AS RowNum,
        c.senderID,c.recipientID,c.messageTime
FROM    dbo.tbl_chatMessages c;

WITH RecursiveCTE
AS(
    SELECT  crt.RowNum,crt.senderID,crt.recipientID,
            crt.messageTime,
            1 AS SessionID
    FROM    @Results crt
    WHERE   crt.RowNum=1
    UNION ALL
    SELECT  crt.RowNum,crt.senderID,crt.recipientID,
            crt.messageTime,
            CASE 
                WHEN DATEDIFF(MINUTE,prev.messageTime,crt.messageTime) <= 10  THEN prev.SessionID
                ELSE prev.SessionID+1
            END
    FROM    @Results crt INNER JOIN RecursiveCTE prev ON crt.RowNum=prev.RowNum+1
    AND     crt.senderID=prev.senderID
    AND     crt.recipientID=prev.recipientID
)
SELECT  *,
        STUFF(CONVERT(VARCHAR(8), DATEADD(SECOND,x.SessionDuration,0), 114), 1,3,'') AS SessionDuration_mmss,
        SUM(x.SessionDuration) OVER() AS SessionDuration_Overall,
        STUFF(CONVERT(VARCHAR(8), DATEADD(SECOND,SUM(x.SessionDuration) OVER(),0), 114), 1,3,'') AS SessionDuration_Overall_mmss
FROM(
    SELECT  r.senderID,r.recipientID,r.SessionID, 
            DATEDIFF(SECOND, MIN(r.messageTime),MAX(r.messageTime)) AS SessionDuration
    FROM    RecursiveCTE r
    GROUP BY r.senderID,r.recipientID,r.SessionID
) x
OPTION(MAXRECURSION 0);

結果:

senderID recipientID SessionID   SessionDuration SessionDuration_mmss SessionDuration_Overall SessionDuration_Overall_mmss
-------- ----------- ----------- --------------- -------------------- ----------------------- ----------------------------
80       79          1           97              01:37                140                     02:20
80       79          2           43              00:43                140                     02:20
于 2013-08-05T06:06:35.337 に答える
0

これが私の解決策の背後にある理由です。まず、チャット期間を開始する各チャットを特定します。これは、前のチャットから 10 分以上経過したチャットを識別するフラグを使用して行うことができます。

次に、このフラグを使用して累積合計を実行します。この合計は、実際にはチャット期間のグループ化識別子として機能します。最後に、結果を集計して、各チャット期間の情報を取得します。

with cmflag as (
      select cm.*,
             (case when datediff(min, prevmessagetime, messagetime) > 10
                   then 0
                   else 1
              end) as ChatPeriodStartFlag
      from (select cm.*,
                   (select top 1 messagetime
                    from tbl_chatMessages cm2
                    where cm2.senderId = cm.senderId or
                          cm2.RecipientId = cm.senderId
                   ) as prevmessagetme
            from tbl_chatMessages cm
           ) cm
     ),
     cmcum as (
      select cm.*,
             (select sum(ChatPeriodStartFlag)
              from cmflag cmf
              where cm2.senderId = cm.senderId or
                    cm2.RecipientId = cm.senderId and
                    cmf.messagetime <= cm.messagetime
             ) as ChatPeriodGroup
      from tbl_chatMessages cm
     )
select cm.SenderId, ChatPeriodGroup, min(messageTime) as mint, max(messageTime) as maxT
from cmcum
group by cm.SenderId, ChatPeriodGroup;

私が完全には理解していないかもしれない課題の 1 つは、送信者と受信者をどのように照合しているかということです。サンプル データのすべての行に同じペアがあります。これは「ユーザー」というSenderId観点から見ていますが、チャット期間中、ユーザーは送信者または受信者のいずれかになる可能性があることを考慮に入れています。

于 2013-08-05T00:58:59.813 に答える
0

テーブル構造のわずかな変更と、チャット サーバー アプリケーション コードの更新に焦点を当てたいと思います (もちろん、可能であれば)。

メッセージ間の遅延が X 分を超えるたびに、チャット サーバーに新しいチャット ID を生成させることはできますか? はいの場合、チャット時間の計算は非常に簡単になります。

于 2013-08-05T09:12:34.867 に答える