用于从会话和消息表连接中选择最新消息的MySql查询

时间:2016-09-07 10:53:08

标签: php mysql sql

请告诉我这段代码有什么问题,这会返回所有会话,但只返回第一个会话的最新消息。

    SELECT 
        conversations.*,
        messages.message,
        patients.first_name as fullname,
        patients.city,
        patients.thumb,
        patients.gender,
        patients.online_status
    FROM 
        patients
    INNER JOIN conversations
        ON conversations.patient_id_fk = patients.id
    LEFT JOIN messages
        ON messages.conversation_id = conversations.id
        AND messages.message_id = 
        (
           SELECT MAX(message_id) 
           FROM messages z
           WHERE z.therapist_id_fk = conversations.therapist_id_fk
        )
    WHERE conversations.therapist_id_fk='1'
    GROUP BY conversations.id
    ORDER BY messages.message_id DESC

4 个答案:

答案 0 :(得分:2)

您希望对话的最大消息不是治疗师,因此我怀疑您希望在此子查询中使用此消息:

    AND messages.message_id = 
    (
       SELECT MAX(message_id) 
       FROM messages z
       WHERE z.message_id = conversations.id
    )

我不确定外部GROUP BY是否正确(可能根本不需要它,它似乎与SELECT的列相冲突),但没有样本数据和所需结果,很难说。

编辑:

我明白了,问题是外部查询中对治疗师id的过滤。这使得这有点复杂:

    AND messages.message_id = 
    (
       SELECT MAX(message_id) 
       FROM messages z JOIN
            conversations c
            ON m.conversation_id = c.id
       WHERE c.therapist_id_fk = 1 AND  -- restriction on subquery
             z.message_id = conversations.id  -- correlation to outer query
    )

除非列是字符串或日期,否则不要对常量使用单引号。

答案 1 :(得分:2)

我能够通过此查询解决问题

|           Method |             Id |                  Name |          Mean |       Error |      StdDev | Rank |
|----------------- |--------------- |---------------------- |--------------:|------------:|------------:|-----:|
|   ManualTruncate | 09123456789093 |          John Johnson |     28.103 ns |   0.6188 ns |   0.8046 ns |    2 |
| OriginalTruncate | 09123456789093 |          John Johnson | 17,953.005 ns | 356.7870 ns | 534.0220 ns |    8 |
|   CachedTruncate | 09123456789093 |          John Johnson |    697.548 ns |  13.6592 ns |  13.4152 ns |    6 |
|   ManualTruncate | 09123456789093 |  Mr. J(...), Esq [98] |     59.177 ns |   1.2251 ns |   1.5494 ns |    4 |
| OriginalTruncate | 09123456789093 |  Mr. J(...), Esq [98] | 18,333.251 ns | 365.0699 ns | 461.6966 ns |    8 |
|   CachedTruncate | 09123456789093 |  Mr. J(...), Esq [98] |    995.924 ns |  19.9356 ns |  23.7319 ns |    7 |
|   ManualTruncate | 09123456789093 | Mr. J(...)hnson [111] |     58.787 ns |   0.4812 ns |   0.4501 ns |    4 |
| OriginalTruncate | 09123456789093 | Mr. J(...)hnson [111] | 18,032.030 ns | 220.0009 ns | 195.0251 ns |    8 |
|   CachedTruncate | 09123456789093 | Mr. J(...)hnson [111] |    977.168 ns |  19.2770 ns |  27.6465 ns |    7 |
|   ManualTruncate |              1 |          John Johnson |      6.800 ns |   0.2039 ns |   0.2651 ns |    1 |
| OriginalTruncate |              1 |          John Johnson | 18,173.803 ns | 192.1153 ns | 170.3052 ns |    8 |
|   CachedTruncate |              1 |          John Johnson |    410.136 ns |   3.8655 ns |   3.6158 ns |    5 |
|   ManualTruncate |              1 |  Mr. J(...), Esq [98] |     34.886 ns |   0.7203 ns |   0.6385 ns |    3 |
| OriginalTruncate |              1 |  Mr. J(...), Esq [98] | 18,013.630 ns | 327.2057 ns | 306.0684 ns |    8 |
|   CachedTruncate |              1 |  Mr. J(...), Esq [98] |    684.351 ns |  12.0877 ns |  11.3069 ns |    6 |
|   ManualTruncate |              1 | Mr. J(...)hnson [111] |     34.285 ns |   0.6136 ns |   0.5124 ns |    3 |
| OriginalTruncate |              1 | Mr. J(...)hnson [111] | 17,926.434 ns | 184.0216 ns | 172.1340 ns |    8 |
|   CachedTruncate |              1 | Mr. J(...)hnson [111] |    685.590 ns |   9.6743 ns |   9.0493 ns |    6 |

我离开了邮件,然后选择最上面的邮件。 Order by可用于按日期给出订单

答案 2 :(得分:1)

    SELECT 
        conversations.*,
        messages.message,
        patients.first_name as fullname,
        patients.city,
        patients.thumb,
        patients.gender,
        patients.online_status
    FROM 
        patients
    INNER JOIN conversations
        ON conversations.patient_id_fk = patients.id
    LEFT JOIN messages
        ON messages.conversation_id = conversations.id
        AND messages.message_id = 
        (
           SELECT MAX(message_id) 
           FROM messages z
           WHERE z.conversation_id = conversations.id
        )
    WHERE conversations.therapist_id_fk='1'
    ORDER BY messages.message_id DESC

发现了这个问题。它在这里:           

          AND messages.message_id = 
            (
               SELECT MAX(message_id) 
               FROM messages z
               WHERE z.conversation_id = conversations.id
            )

我正在使用它:

        AND messages.message_id = 
        (
           SELECT MAX(message_id) 
           FROM messages z
           WHERE z.therapist_id_fk = conversations.therapist_id_fk
        )

答案 3 :(得分:0)

你的问题是:

SELECT MAX(message_id) 
FROM messages z
WHERE z.therapist_id_fk = conversations.therapist_id_fk

此查询仅匹配一条消息。你需要的东西有点不同。 试试这个:

SELECT 
    conversations.*,
    messages.message,
    patients.first_name as fullname,
    patients.city,
    patients.thumb,
    patients.gender,
    patients.online_status
FROM 
    patients
INNER JOIN conversations
    ON conversations.patient_id_fk = patients.id
LEFT JOIN messages
    ON messages.conversation_id = conversations.id        
WHERE conversations.therapist_id_fk='1' 
      AND messages.message_id IN (  -- new bit
          SELECT MAX(message_id) FROM messages z GROUP BY z.conversation_id
      )
GROUP BY conversations.id
ORDER BY messages.message_id DESC