如果你们可以帮助我,我需要在sqlite3中做一些复杂的选择吗?
我有一个'消息'表,其中包含以下字段:
from | to | message_text | message_timestamp
和行:
a | b | Hi | 101
a | b | How are you? | 103
b | a | Fine,thanks | 104
c | a | Hey dude! | 115
a | b | I need to tell you something. | 1102
d | b | Yo dude | 1234
b | d | Yea dude, whatsup? | 1443
我想按时间顺序从上述对话中选择最后一条消息,忽略消息是从x发送到y还是从y发送到x,应该考虑xy或yx对。所以对于上面的例子,你会得到这样的东西:
b | d | Yea dude, whatsup? | 1443
a | b | I need to tell you something. | 1102
c | a | Hey dude! | 115
谢谢!
答案 0 :(得分:1)
这里使用的一个技巧是使用标量最小/最大技巧来收集从/到或从/从对中共享相同逻辑组的记录。在下面的查询中,最里面的子查询存储桶会从b
到d
收集到从d
到b
的同一个存储桶中。然后我们对此进行聚合以找到最新的时间戳,最后连接回原始表以检索所需的整行。
SELECT
m1.*
FROM messages m1
INNER JOIN
(
SELECT
t."from",
t."to",
MAX(t.message_timestamp) AS max_ts
FROM
(
SELECT
MIN("from", "to") AS "from",
MAX("from", "to") AS "to",
message_text,
message_timestamp
FROM messages
) t
GROUP BY
t."from",
t."to"
) m2
ON MIN(m1."from", m1."to") = m2."from" AND
MAX(m1."from", m1."to") = m2."to" AND
m1.message_timestamp = m2.max_ts
ORDER BY m1.message_timestamp DESC;
注意:在命名列(或表或数据库)时,不要使用from
和to
等SQL关键字。我需要用双引号转义from
以使查询起作用。
<强>输出:强>
在这里演示:
(演示在MySQL中,因为Rextester不支持SQLite。唯一的区别是MIN
被LEAST
取代,而且列的转义略有不同。)
答案 1 :(得分:0)
合并两个临时结果,一个包含from
/ to
,另一个包含to
/ from
。然后通过强制第一列中的值小于第二列中的值来过滤掉重复项。然后,您可以对这些列进行简单分组:
SELECT c1,
c2,
message_text,
max(message_timestamp)
FROM (SELECT "from" AS c1, "to" AS c2, message_text, message_timestamp
FROM messages
WHERE "from" < "to"
UNION ALL
SELECT "to", "from", message_text, message_timestamp
FROM messages
WHERE "to" < "from"
)
GROUP BY c1, c2;
(使用bare columns in an aggregated query需要SQLite 3.7.11或更高版本。)