首先,我想为我问题的模糊标题道歉。由于我不是SQL方面的专家,因此我很难解释这种情况。
我在撰写查询时需要帮助。
我有一个名为 HELLO-MESSAGES 的表格,其中包含多个列: ID , From , To ,正文,已发送(已发送消息的数据)。
我有这些行:
我想做的是在表格中显示所有不同的聊天记录。如果我的电话号码是 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?谢谢!
答案 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的表达式。 (这些行需要按from
和to
的不同组合值进行折叠/分组。修复该行的一种方法是向{{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