我有两个没有通过外键连接的表。
一个叫message_log
,另一个叫assigned_conversation
。
assigned_conversation
还包含match_id
列
我下面有没有问题的查询。
SELECT m.*
FROM message_log m
WHERE m.from_id <> 'MYID'
AND m.to_id = 'MYID'
AND m.unix_timestamp = (SELECT Max(unix_timestamp)
FROM message_log
WHERE match_id = m.match_id
GROUP BY match_id)
我唯一想更改的查询就是结果的排序方式。
是否有可能对结果进行排序,以便将match_id
表中存在的assigned_conversation
s放在结果的顶部,而对于match_id
s assigned_conversation
表中是否不存在要排序的assigned_conversation
表中存在的那些?
答案 0 :(得分:2)
一种选择是使用CASE
表达式进行排序,该表达式检查是否可以在match_id
表中找到外部查询中给定的assigned_conversation
。
SELECT m.*
FROM message_log m
WHERE m.from_id <> 'MYID'
AND m.to_id = 'MYID'
AND m.unix_timestamp = (SELECT Max(unix_timestamp)
FROM message_log
WHERE match_id = m.match_id
GROUP BY match_id)
ORDER BY
CASE WHEN EXISTS (SELECT 1 FROM assigned_conversation a
WHERE a.match_id = m.match_id)
THEN 0 ELSE 1 END;
请注意,我们可以尝试不加入assigned_conversation
,但这可能会在您的结果集中引入重复项,假设外部查询中的match_id
在{{1}中可能出现多次}。使用assigned_conversation
可以解决此问题。
答案 1 :(得分:0)
除了执行子查询,您还可以使用distinct来确保仅获取最新的日志条目,然后通过左键加入assigned_conversation并按首先match_id为null的顺序进行排序,然后使用m.unix_timestamp desc可以得到预期的结果一种干净高效的方式
SELECT DISTINCT m.*
FROM message_log m
left join assigned_conversation ac on ac.match_id = m.match_id
WHERE m.from_id <> 'MYID'
AND m.to_id = 'MYID'
ORDER BY ac.match_id is null, m.unix_timestamp desc
答案 2 :(得分:0)
我将查询简化为:
SELECT DISTINCT ON (ml.match_id) ml.*
FROM message_log ml
WHERE ml.from_id <> 'MYID' AND
ml.to_id = 'MYID'
ORDER BY ml.match_id, ml.unix_timestamp DESC;
然后您可以将其用作子查询来获取所需的最终订单:
SELECT ml.*
FROM (SELECT DISTINCT ON (ml.match_id) ml.*
FROM message_log ml
WHERE ml.from_id <> 'MYID' AND
ml.to_id = 'MYID'
ORDER BY ml.match_id, ml.unix_timestamp DESC
) ml
ORDER BY (EXISTS (SELECT 1 FROM assigned_conversation ac WHERE ac.match_id = ml.match_id))::int DESC,
match_id;
但是,我倾向于将标志添加到结果集中的数据中:
SELECT ml.*
FROM (SELECT DISTINCT ON (ml.match_id) ml.*,
(EXISTS (SELECT 1 FROM assigned_conversation ac WHERE ac.match_id = ml.match_id))::int as ac_flag
FROM message_log ml
WHERE ml.from_id <> 'MYID' AND
ml.to_id = 'MYID'
ORDER BY ml.match_id, ml.unix_timestamp DESC
) ml
ORDER BY ac_flag desc, match_id;