2

ユーザーの受信トレイの最後の10件の会話を選択するには、特定のSQLクエリが必要です。受信トレイには、すべてのユーザーとの会話(スレッド)のみが表示されます。会話から最後のメッセージが選択され、受信トレイに表示されます。

編集しました。

期待される結果:latest messageのそれぞれから抽出します10 latest conversations。Facebookは同じように最新の会話を表示します

そしてもう1つ質問があります。pagination次のページで前の最新の会話から次の10の最新のメッセージを表示するようにするにはどうすればよいですか?

データベース内のプライベートメッセージは次のようになります。

| id | user_id | recipient_id | text
| 1  | 2       | 3            | Hi John!
| 2  | 3       | 2            | Hi Tom! 
| 3  | 2       | 3            | How are you? 
| 4  | 3       | 2            | Thanks, good! You?
4

4 に答える 4

2

私の理解によると、ユーザーごとに会話の最新のメッセージを取得する必要があります(過去10回の最新の会話のうち)

更新:latest_conversation_message_idすべてのユーザーの会話を取得するようにクエリを変更しました

以下のクエリは、の詳細を取得します。他のユーザーが取得user_id = 2できるように変更できます。users.id = 2

SQLFiddle、これがあなたの目的を解決することを願っています

SELECT
    user_id, 
    users.name, 
    users2.name as sent_from_or_sent_to,
    subquery.text as latest_message_of_conversation
FROM
    users
    JOIN
    (
    SELECT
        text,
        row_number() OVER ( PARTITION BY user_id + recipient_id ORDER BY id DESC) AS row_num,
        user_id,
        recipient_id,
        id
    FROM
        private_messages
    GROUP BY
        id,
        recipient_id,
        user_id,
        text
    ) AS subquery ON ( ( subquery.user_id = users.id OR subquery.recipient_id = users.id)  AND row_num = 1 )
    JOIN users as users2 ON ( users2.id = CASE WHEN users.id = subquery.user_id THEN subquery.recipient_id ELSE subquery.user_id END )
WHERE
    users.id = 2
ORDER BY
    subquery.id DESC
LIMIT 10

情報:クエリは、他のユーザーとのすべての会話の最新メッセージを取得します。がにuser_id 2メッセージを送信するuser_id 3と、会話の開始を示すメッセージも表示されます。他のユーザーとのすべての会話の最新メッセージが表示されます

于 2013-03-24T08:40:34.440 に答える
1

pgのgroupwise-maxを解くには、を使用できますDISTINCT ON。このような:

SELECT
DISTINCT ON(pm.user_id)
    pm.user_id, 
    pm.text
FROM
    private_messages AS pm
WHERE pm.recipient_id= <my user id>
ORDER BY pm.user_id, pm.id DESC;

http://sqlfiddle.com/#!12/4021d/19

ただし、最新のXを取得するには、副選択で使用する必要があります。

SELECT
q.user_id,
q.id,
q.text
FROM
(
SELECT
DISTINCT ON(pm.user_id)
    pm.user_id,
pm.id,
    pm.text
FROM
    private_messages AS pm
WHERE pm.recipient_id=2
ORDER BY pm.user_id, pm.id DESC
  ) AS q
ORDER BY q.id DESC
LIMIT 10;   

http://sqlfiddle.com/#!12/4021d/28

送信スレッドと受信スレッドの両方を取得するには:

SELECT
q.user_id,
q.recipient_id,
q.id,
    q.text
FROM
(
SELECT
DISTINCT ON(pm.user_id,pm.recipient_id)
    pm.user_id,
    pm.recipient_id,
pm.id,
    pm.text
FROM
    private_messages AS pm
WHERE pm.recipient_id=2 OR pm.user_id=2
ORDER BY pm.user_id,pm.recipient_id, pm.id DESC
  ) AS q
ORDER BY q.id DESC
LIMIT 10;

http://sqlfiddle.com/#!12/4021d/42

于 2013-03-24T10:21:39.070 に答える
0

WHERE句の後に貼り付けます

ORDER BY "ColumnName" [ASC, DESC]

W3SchoolsでのUNIONの説明は、この2つのステートメントの結果を組み合わせたものです。

SELECT "ColumnName" FROM "TableName"
UNION
SELECT "ColumnName" FROM "TableName"
于 2013-03-24T07:55:42.297 に答える
0

大規模なデータセットの場合、(user_idとid)または(recipient_idとid)のインデックススキャンが最新の10の会話を取得するのに非常に効率的であるため、2つのステートメントを実行してから、結果を統合してみてください。各タイプ。

with sent_messages as (
  SELECT   *
  FROM     private_messages
  WHERE    user_id = my_user_id
  ORDER BY id desc
  LIMIT    10),
received_messages as (  SELECT   *
  FROM     private_messages
  WHERE    recipient_id = my_user_id
  ORDER BY id desc
  LIMIT    10),
all_messages as (
  select *
  from   sent_messages
  union all
  select *
  from   received_messages)
select   *
from     all_messages
order by id desc
limit    10

編集:実際に試す価値のある別のクエリは次のようになります:

select *
from   private_messages
where  id in (
         select id
         from   (
           SELECT   id
           FROM     private_messages
           WHERE    user_id = my_user_id
           ORDER BY id desc
           LIMIT    10
           union all
           SELECT   id
           FROM     private_messages
           WHERE    recipient_id = my_user_id
           ORDER BY id desc
           LIMIT    10) all_ids
          order by id desc
          limit 10) last_ten_ids
order by id desc

これは、インデックスのみを使用してIDを取得できる9.2+の場合、または取得する最新の番号が非常に大きい場合に適している可能性があります。それでもまだ少し不明確です。疑わしい場合は、前のバージョンを選択します。

于 2013-03-24T10:28:55.023 に答える