我一直在努力使用MySQL查询,似乎我找不到任何问题的解决方案。
我有一个文件数据库,我想按时间订购。非常简单。复杂性如下:如果两个或多个文档在名为correlation_id
的列中共享相同的值,我希望它们彼此相邻放置。如果我只是先按correlation_id
排序,相关的行将放在顶部或底部。我希望将它们放在最新文档的位置。
例如,假设我有一个文档列表,文档B
和D
与id“相关”,只是它们在列中共有的数字。
当我使用ORDER BY time
时,输出为:
time document correlation_id
1h A 0
2h B 1
4h C 0
4h D 1
6h E 0
当我使用ORDER BY correlation_id, time
时,表格主要按相关性排序,并给出:
time document correlation_id
2h B 1
4h D 1
1h A 0
4h C 0
6h E 0
我不希望相关项目位于顶部或下方,而是位于最新文档的位置,因此它看起来像:
time document correlation_id
1h A 0
2h B 1
4h D 1
4h C 0
6h E 0
作为查询,它必须看起来像:
SELECT * FROM DOCUMENTS ORDER BY [if (correlation_id<>0) {order by correlation_id first}], time DESC
提前谢谢。
答案 0 :(得分:0)
Demo at Rextester以下两个答案。
我不支持在选择中使用选择...加入以获得最短时间,分组似乎更难以维护;并增加了混乱。因此,select in select可能更容易理解和维护,但从长远来看它应该更慢。
我们使用select来获取每个非0 correlation_ID的最小时间;对于那些零,我们只使用记录时间。并合并这两个值,为我们提供一个MinTime列,然后我们可以先按顺序排序,然后按时间排序以获得所需的排序。
SELECT BaseSet.*, coalesce((SELECT min(time) MT
FROM DOCUMENTS MinCorT
WHERE MinCorT.Correlation_ID = BaseSet.Correlation_ID
and correlation_ID <> 0), time) MINTIME
FROM documents BaseSet
ORDER BY MINTIME, Time
我认为另一种方法更快(更多的是你拥有的行......)但更难以理解/维护。
SELECT BaseSet.*, coalesce(MinCorT.MinTime, BasetSet.Time) MinTime
FROM documents BaseSet
LEFT JOIN (SELECT min(Time) MinTime, Correlation_ID
FROM Documents MinCorT
WHERE Correlation_ID <> 0
GROUP BY Correlation_Id) B
on BaseSet.Correlation_ID = MinCorT.Correlation_ID
ORDER BY MinTime, time
第二个查询假设您有关于correlation_ID,time的索引第二个查询更快的原因是因为它只需要进行一次连接。而第一个查询必须为文档中的每个记录执行子查询。因此,您可以看到查询的文档越多,查询就越慢。
第二个查询生成包含每个correlation_ID的最小时间的数据子集(MinCorT)。我们将基集连接到此集合,因此我们有每个文档的最小时间具有correlation_ID。我们使用coalesce在correlation_ID为0(无最小时间记录)的情况下使用基本文档时间。我们再次得到一个MinTime列,我们可以按顺序列和时间列来生成所需的顺序。
第二种方法是更多的代码,因此更难以维护,但从长远来看应该以更高的性能运行。
鉴于您的样本数据;两个查询都会导致:
+------+----------+----------------+---------+
| Time | document | Correlation_ID | MinTime |
+------+----------+----------------+---------+
| 1h | A | 0 | 1h |
| 2h | B | 1 | 2h |
| 4h | D | 1 | 2h |
| 4h | C | 0 | 4h |
| 6h | E | 0 | 6h |
+------+----------+----------------+---------+
虽然在第二个中我们可以将合并向下移动到顺序,但根本没有MinTime列。但是为了理解,我以为我会展示它。