选择分组行列表,显示最近的内容

时间:2012-03-13 23:07:28

标签: mysql

不是最好的头衔,我道歉。

表格结构:

讯息

  • id - int
  • message - varchar
  • user - varchar
  • date - varchar
  • from - varchar

联系人

  • contactId - int
  • contactUser - varchar
  • contactName - varchar
  • contactFrom - varchar

我的查询目前是:

 SELECT
     messages1.`from`,
     messages1.`message`,
     messages1.`date` AS d,
     messages2.`count`,
     contacts.`contactId`,
     contacts.`contactName`,
     contacts.`contactFrom`
 FROM messages AS messages1,
   (
          SELECT
              MAX(`date`) AS maxdate,
             `from`,
             COUNT(*) AS `c`
          FROM messages
          WHERE
             `user` = 'MYUSER'
          GROUP BY `from`
   ) AS messages2
LEFT JOIN contacts ON
   (
       contacts.`contactUser` = 'MYUSER' AND
       contacts.`contactsFrom` = messages2.`from`
   )
WHERE
   messages1.`from`= messages2.`from` AND
   messages1.`date` = messages2.`date`
ORDER BY `date` DESC;

然而,当用户对两个不同的用户具有相同的联系人时,他们将获得相同的“对话”两次。

例如:

如果存在以下数据:

联系人

| contactId | contactUser |  contactName | contactFrom |
|-----------|-------------|--------------|-------------|
|     1     |   giggsey   |  MyNameOne   | +1234567890 |
|     2     |   giggsey   | MySecondName | +1234567890 |

讯息

|  id  |  message  |   user   |    date    |     from     |
|------|-----------|----------|------------|--------------|
|   1  |     h1    | giggsey  | 111111111  | +1234567890  |
|   2  |     h2    | giggsey  | 111111113  | +1234567890  |
|   3  |   random  | giggsey  | 111111116  | +9999992234  |
|   4  |     h3    | giggsey  | 111111119  | +1234567890  |

然后查询返回:

|     from    | message |      d    | count | contactId |  contactName | contactFrom |
|-------------|---------|-----------|-------|-----------|--------------|-------------|
| +1234567890 |    h3   | 111111119 |   3   |     1     |   MyNameOne  | +1234567890 |
| +1234567890 |    h3   | 111111119 |   3   |     2     | MySecondName | +1234567890 |
| +9999992234 |  random | 111111116 |   3   |  (NULL)   |     (NULL)   |   (NULL)    |

正如您在上面所看到的那样,它会返回相同的“对话”两次,但是对于联系人的每个副本都会返回一次。

我很确定这是因为JOIN,但我似乎找不到原因。

1 个答案:

答案 0 :(得分:0)

通过使用子查询而不是仅从表中读取来修复它。

 SELECT
     messages1.`from`,
     messages1.`message`,
     messages1.`date` AS d,
     messages2.`count`,
     contacts.`contactId`,
     contacts.`contactName`,
     contacts.`contactFrom`
 FROM messages AS messages1,
   (
          SELECT
              MAX(`date`) AS maxdate,
             `from`,
             COUNT(*) AS `c`
          FROM messages
          WHERE
             `user` = 'MYUSER'
          GROUP BY `from`
   ) AS messages2
LEFT JOIN
  (
      SELECT
          *
      FROM
         `contacts`
      GROUP BY `contactsFrom`
  ) contacts ON
   (
       contacts.`contactUser` = 'MYUSER' AND
       contacts.`contactsFrom` = messages2.`from`
   )
WHERE
   messages1.`from`= messages2.`from` AND
   messages1.`date` = messages2.`date`
ORDER BY `date` DESC;