【问题标题】:Select list of grouped rows, showing content of most recent选择分组行列表,显示最近的内容
【发布时间】:2012-03-30 10:01:11
【问题描述】:

这不是最好的标题,我很抱歉。

表结构:

消息

  • id - int
  • 消息 - varchar
  • 用户 - varchar
  • 日期 - varchar
  • 来自 - varchar

联系人

  • contactId - 整数
  • contactUser - varchar
  • 联系人姓名 - 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,但我似乎无法弄清楚原因。

【问题讨论】:

  • 查询中的标识符与文本中的标识符不匹配。例如,您的查询引用了contacts.from,但您的文本没有提到contacts 上的from 字段。
  • @ruakh 同上,复制/粘贴失败。
  • 如果您澄清您的架构,您可能会发现您会得到更好的响应。您的消息表具有字段userfrom。这些是否可以更好地表示为to_user_idfrom_user_iddate 字段 - 这是 DATE 字段吗?如果它是一个 DATETIME 字段,则最好将其命名为 sentcreated。为什么字段名称的命名风格混合 - 有些以表名前缀有些没有?查询中连接语法的混合非常可怕。如果您希望人们努力回答您的问题,也许您应该更加努力地提出问题?
  • @nnichols 感谢您的反馈,我已经更新了问题,是否更清楚了?
  • 感谢您更新问题。现在和预期的一样清晰得多。您的加入contacts.contactsFrom = messages2.from 是从一排到两排。无法从联系人中提取单个记录,因为消息中没有外键链接到联系人中的唯一键。如果您希望以这种方式将 contactFrom 视为键,则它必须是唯一的。

标签: mysql


【解决方案1】:

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

 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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-27
    相关资源
    最近更新 更多