0

Facebookの現在のメッセージボックス(「会話」のリストが含まれています)のように、現在のユーザーが別のユーザーとの間で送受信した最後のメッセージのリストをデータベースから取り出そうとしています。

サンプルデータ:

msg_id sender_id target_id date_sent content ...
  1        2         4        20       bla   ...
  2        2         5        21       bla   ...
  3        2         6        22       bla   ...
  4        4         2        25       bla   ...
  5        5         6        26       bla   ...
  6        4         2        50       bla   ...

現在のユーザーが 2 の場合、2 が他のユーザーとの最後のメッセージ (送信または受信) のみを取得したい

希望するデータは次のとおりです。

msg_id sender_id target_id date_sent content ...
  6        4         2        50       bla   ...
  2        2         5        21       bla   ...
  3        2         6        22       bla   ...

msg_id 6 が存在するのは、(送信者/受信者が誰であるかに関係なく) メッセージ 2 と 4 が持っていたすべてのメッセージの中で最も大きな日付 (50) を持っているためです。msg_id 2 と 3 が存在します。 6 (それぞれに 1 つのメッセージを送信)

これを実現する方法が見つかりませんでした。送信者 ID と受信者 ID の両方を含む一意に生成されたフィールドに group_by を含める必要がありますか? わかりません、助けてください

アップデート:

私はアイデアが気に入り、最終的に別の新しいフィールドを持つそのテーブルのビューを作成しました。このフィールドには、2 つの ID を順番に (大きい方が先に) アンダースコアで区切られた連結が含まれています。このように、そのフィールドは各会話に固有です。次に、それによってグループ化します:)

4

4 に答える 4

2

テストされていない例を次に示します。他の方法もあります。検索すると、これはかなり一般的な質問です。

SELECT t1.*
FROM 
  msg_table AS t1
LEFT JOIN msg_table AS t2
  ON ((t1.sender_id = t2.sender_id AND t1.target_id = t2.target_id) 
    OR (t1.sender_id = t2.target_id AND t1.target_id = t2.sender_id))
    AND t1.msg_id < t2.msg_id
WHERE (t1.sender_id = ? OR t1.target_id = ?) AND t2.msg_id IS NULL
于 2013-01-21T09:57:42.327 に答える
0

私はあなたがここで撮影しているものと同様のことをしました。しかし、簡単にするために、convoID というテーブルに別の列を追加しました。これは一意の ID ではなく、ユーザーが既に通信しているユーザーからメッセージを送受信するたびに再利用される ID です。次に、テーブルからすべての convoID を取得します (ただし、重複はありません)。

SELECT DISTINCT convoID FROM table WHERE sender='$user' OR recipient='$user'

このようにして、同じ 2 人の間のすべてのメッセージに会話として簡単にアクセスできます。そこから、次のような会話から最新のメッセージを取得できます。

SELECT message FROM table WHERE convoID='$thisConvoID' ORDER BY time DESC LIMIT 0,1;

私にとって、これはそれを行うための最も混乱の少ない方法であり、うまく機能しました-何かについて明確にする必要がある場合は、質問してください.

于 2013-01-23T03:35:52.863 に答える
0

それは少し面倒かもしれません。

簡単なプレイがあれば、このようなものが仕事をします。ただし、これにより、送信者に送信された最新のメッセージと、送信者から送信された最新のメッセージ (必要と思われる最新のメッセージではなく) と、その送信者から各受信者への最新のメッセージが取得されます。

未検証ですので誤字脱字はご容赦ください。

SELECT a.msg_id, a.sender_id, a.target_id, a.date_sent, a.content
FROM someTable a
INNER JOIN (SELECT sender_id As SomeBod, MAX(date_sent) AS date_sent
FROM someTable
WHERE sender_id = 2
GROUP BY sender_id) sub1
ON a.sender_id = sub1.SomeBod 
AND a.date_sent = sub1.date_sent
UNION 
SELECT b.msg_id, b.sender_id, b.target_id, b.date_sent, b.content
FROM someTable b
INNER JOIN (SELECT target_id As SomeBod, MAX(date_sent) AS date_sent
FROM someTable
WHERE target_id = 2
GROUP BY target_id) sub2
ON b.target_id = sub2.SomeBod 
AND b.date_sent = sub2.date_sent
UNION
SELECT c.msg_id, c.sender_id, c.target_id, c.date_sent, c.content
FROM someTable c
INNER JOIN (SELECT sender_id, target_id, MAX(date_sent) AS date_sent
WHERE sender_id = 2
GROUP BY sender_id, target_id) sub3
ON a.sender_id = sub3.sender_id 
AND b.target_id = sub3.target_id 
AND b.date_sent = sub3.date_sent
于 2013-01-21T09:42:07.703 に答える
0

おそらく、sender_id と target_id を組み合わせて計算値にし、それに対して "LIKE" クエリを実行するようなことを行うことができます。

しかし、正直なところ、単純な 2 つのクエリを実行し、その結果をコードでマージするだけで、パフォーマンスが向上すると思います。コードの保守も容易になります。

于 2013-01-21T09:43:35.010 に答える