如何进行特定的SELECT查询

时间:2016-01-12 16:35:02

标签: mysql sql

首先,我想为我问题的模糊标题道歉。由于我不是SQL方面的专家,因此我很难解释这种情况。

我在撰写查询时需要帮助。

我有一个名为 HELLO-MESSAGES 的表格,其中包含多个列: ID From To 正文已发送(已发送消息的数据)。

我有这些行:

  1. 1,345xxxxxxx,339xxxxxxx,"嘿,你好吗?",12/1/2016 17:24
  2. 2,339xxxxxxx,345xxxxxxx,"非常感谢,你呢?",12/1/2016 17:25
  3. 3,545xxxxxxx,340xxxxxxx,"快速...",12/1/18 18:24
  4. 我想做的是在表格中显示所有不同的聊天记录。如果我的电话号码是 345xxxxxxx ,我想显示一个包含以下布局的表格:

    find $dirsPATH -mindepth 1 -maxdepth 2 -type d -mtime +2
    

    例如,就像WhatsApp或任何其他IM一样。我想显示我正在聊天的人的号码,以及该聊天中发送的最后一条消息。我在编程查询方面遇到了非常糟糕的经历:这是我到目前为止所做的:

    <table>
      <tr>
        <td><b>339xxxxxxx</b><br>Fine thanks, and you?</td>
      </tr>
      <tr>
        <td><b>340xxxxxxx</b><br>The quick...</td>
      </tr>
    </table>
    

    但它按预期返回每条消息!

    请帮助一个不太喜欢SQL的初学者:)

    修改

    SELECT * FROM 'HELLO-MESSAGES' WHERE 'From'='345xxxxxxx' OR 'To'='345xxxxxxx'
    

    是的,@ spencer7593?谢谢!

3 个答案:

答案 0 :(得分:1)

你在寻找什么,我认为并不那么简单,你需要对sql有很好的了解。我认为答案在以下链接中:

Get Last conversation row from MySQL database table

希望这会对你有所帮助。 最好的问候!

答案 1 :(得分:1)

正如我在评论中指出的,对于具有大量行的表,为了提高查询性能,我会考虑实现一个额外的&#34;最新消息&#34;要与HELLO-MESSAGES表一起维护的表。但是我没有深入研究,因为那并没有解决你提出的具体问题。 (但我怀疑你会问如何提高查询的性能,以获得最新消息&#34; ......除了确保适当的索引可用,并且该表增长到显着大小。)

在每个&#34;会话中获取最新消息&#34;从发送特定的电话号码,您可以使用以下查询:

SELECT df.id
     , df.from
     , df.to
     , df.sent
     , df.body
  FROM ( SELECT xf.from
              , xf.to
              , MAX(xf.sent) AS max_date
           FROM `HELLO-MESSAGES` xf
          WHERE xf.from = '345xxxxxxx'
          GROUP BY xf.from, xf.to
       ) mf
  JOIN `HELLO-MESSAGES` df
    ON df.from = mf.from
   AND df.to   = mf.to
   AND df.sent = mf.max_date

如果有多条消息具有相同的最大值&#34;已发送&#34;对于给定的对话,此查询将返回所有这些行。

可以使用相应的查询来获取每个&#34;会话中的最新消息。这是由特定的电话号码收到的。

SELECT dt.id
     , dt.from
     , dt.to
     , dt.sent
     , dt.body
  FROM ( SELECT xt.from
              , xt.to
              , MAX(xt.sent) AS max_date
           FROM `HELLO-MESSAGES` xt
          WHERE xt.to = '345xxxxxxx'
          GROUP BY xt.to, xt.from
       ) mt
  JOIN `HELLO-MESSAGES` dt
    ON dt.from = mt.from
   AND dt.to   = mt.to
   AND dt.sent = mt.max_date

我们可以合并这两个查询的结果,并返回这些消息的唯一id值。我们可以将这些集合与UNION ALL运算符组合在一起。 (MySQL优化器通常不能很好地处理&#39; OR&#39;谓词;这就是将查询分成两部分的原因。)

SELECT df.id
  FROM ( SELECT xf.from
              , xf.to
              , MAX(xf.sent) AS max_date
           FROM `HELLO-MESSAGES` xf
          WHERE xf.from = '345xxxxxxx'
          GROUP BY xf.from, xf.to
       ) mf
  JOIN `HELLO-MESSAGES` df
    ON df.from = mf.from
   AND df.to   = mf.to
   AND df.sent = mf.max_date

 UNION ALL

SELECT dt.id
  FROM ( SELECT xt.from
              , xt.to
              , MAX(xt.sent) AS max_date
           FROM `HELLO-MESSAGES` xt
          WHERE xt.to = '345xxxxxxx'
          GROUP BY xt.to, xt.from
       ) mt
  JOIN `HELLO-MESSAGES` dt
    ON dt.from = mt.from
   AND dt.to   = mt.to
   AND dt.sent = mt.max_date

此查询返回的集合将包含最新&#34;已发送&#34;的id值。并且&#34;收到&#34;每个对话中的消息。

如果我们保证&#34;稍后&#34;行的id值。消息将大于&#34;更早&#34;行的id值。消息,我们可以利用这一点来处理多个&#34;最新&#34;的问题。对话中的消息;两个或多个具有相同值Sent的行。

我们可以使用它将前一个查询的结果减少到每个对话中的最新消息。我们会在下一个查询中将上一个查询的结果重新表示为q1

SELECT MAX(d.id) AS max_id
  FROM (
         subquery
       ) q1
  JOIN `HELLO-MESSAGES` d
    ON d.id = q1.id
 GROUP BY IF(d.from<d.to,d.from,d.to), IF(d.from<d.to,d.to,d.from) 

获取我们想要返回的消息的id值。我们会在下一个查询中将该结果表示为q2

SELECT r.id
     , r.from
     , r.to
     , r.sent
     , r.body
  FROM (
       ) q2
  JOIN `HELLO-MESSAGES` r
    ON r.id = q2.max_id
 ORDER BY r.sent DESC, r.id DESC

总而言之,我们得到了一个非常难看的问题:

SELECT r.id
     , r.from
     , r.to
     , r.sent
     , r.body
  FROM (

         SELECT MAX(d.id) AS max_id
           FROM (

                  SELECT df.id
                    FROM ( SELECT xf.from
                                , xf.to
                                , MAX(xf.sent) AS max_date
                             FROM `HELLO-MESSAGES` xf
                            WHERE xf.from = '345xxxxxxx'
                            GROUP BY xf.from, xf.to
                         ) mf
                    JOIN `HELLO-MESSAGES` df
                      ON df.from = mf.from
                     AND df.to   = mf.to
                     AND df.sent = mf.max_date

                   UNION ALL

                  SELECT dt.id
                    FROM ( SELECT xt.from
                                , xt.to
                                , MAX(xt.sent) AS max_date
                             FROM `HELLO-MESSAGES` xt
                            WHERE xt.to = '345xxxxxxx'
                            GROUP BY xt.to, xt.from
                         ) mt
                    JOIN `HELLO-MESSAGES` dt
                      ON dt.from = mt.from
                     AND dt.to   = mt.to
                     AND dt.sent = mt.max_date

                ) q1
           JOIN `HELLO-MESSAGES` d
             ON d.id = q1.id
          GROUP BY IF(d.from<d.to,d.from,d.to),IF(d.from<d.to,d.to,d.from)

       ) q2
  JOIN `HELLO-MESSAGES` r
    ON r.id = q2.max_id
 ORDER BY r.sent DESC, r.id DESC

编辑:缺少含糊不清的列引用的限定符

编辑:修复了GROUP BY中q2的表达式。 (这些行需要按fromto的不同组合值进行折叠/分组。修复该行的一种方法是向{{1}添加表达式该修复程序适用于上述查询。

这个答案说明了一种返回指定结果的方法。这不一定是最好的方法。内联视图(在MySQL版本中使用派生表)的使用可能会导致(有时很大的)性能损失。

答案 2 :(得分:0)

您可以将字符串与 LIKE 函数进行比较。在你的情况下:

SELECT * FROM `HELLO-MESSAGES` WHERE `From` LIKE "345%" OR `To` LIKE "345%" ORDER BY `Sent` DESC LIMIT 1;

查看更多:http://dev.mysql.com/doc/refman/5.7/en/string-comparison-functions.html