sql有没有一种方法可以将多个时间列排序为一个列,同时保留元数据而不合并?

wsxa1bj1  于 2021-06-18  发布在  Mysql
关注(0)|答案(2)|浏览(282)

这是我上一个问题的扩展:sql有没有一种方法可以在保留元数据的同时将多个时间列排序为一个时间列?
我现在正在尝试优化这个解决方案,但现在我遇到了第一个timestamp列被排序的情况。union作为一种解决方案的问题是,它大大增加了查询大型数据集的时间,因为它实际上再次将数据放在无序的位置,并且需要在时间戳上另一个order by。
因此,总结一下前面的问题:我有一个sql数据库表,它有四列,每列的时间不同,并在第一个时间戳(a\u time)上排序。我希望能够以这样一种方式对它们进行排序:我可以将a、b、c和d时间戳合并到一列中,同时保留id和元数据。

id | a_time | b_time | c_time | d_time | metadata1 | metadata2
1  | 5      | 7      | 2      | 4      | a         | b
2  | 6      | 1      | 12     | 10     | c         | d
3  | 8      | 9      | 3      | 11     | e         | f

在上面的例子中,我想要一些结果:

id | time | metadata1 | metadata2
2  |  1   |     c     |    d
1  |  2   |     a     |    b
3  |  3   |     e     |    f
1  |  4   |     a     |    b
1  |  5   |     a     |    b
2  |  6   |     c     |    d
1  |  7   |     a     |    b
3  |  8   |     e     |    f
3  |  9   |     e     |    f
2  |  10  |     c     |    d
3  |  11  |     e     |    f
2  |  12  |     c     |    d

我认为没有其他方法可以做到这一点,我可能需要以不同的方式解析查询数据,但我很欣赏对这个问题的可能优化解决方案的任何见解。

w1e3prcc

w1e3prcc1#

如果你有一个数字表,你可以通过 JOIN 将其添加到元数据表:

SELECT m.id, n.n, m.metadata1, m.metadata2
FROM numbers n
JOIN metadata m ON m.a_time = n.n OR m.b_time = n.n OR m.c_time = n.n OR m.d_time = n.n
ORDER BY n.n

输出

id  n   metadata1   metadata2   
2   1   c           d
1   2   a           b
3   3   e           f
1   4   a           b
1   5   a           b
2   6   c           d
1   7   a           b
3   8   e           f
3   9   e           f
2   10  c           d
3   11  e           f
2   12  c           d

如果没有数字表,可以使用以下查询动态创建:

SELECT m.id, n.n, m.metadata1, m.metadata2
FROM (SELECT n1.n + n10.n * 10 AS n 
      FROM (SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) n1
           CROSS JOIN
           (SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) n10
           ) n
JOIN metadata m ON m.a_time = n.n OR m.b_time = n.n OR m.c_time = n.n OR m.d_time = n.n
ORDER BY n.n

sqlfiddle公司
更新
出于性能原因,最好添加 WHERE 限制从 numbers 表中的时间范围 metadata

WHERE n.n <= (SELECT GREATEST(MAX(a_time), MAX(b_time), MAX(c_time), MAX(d_time)) FROM metadata)

将索引添加到 a_time , b_time , c_time 以及 d_time 还可以提高此查询的性能。

vbopmzt1

vbopmzt12#

你好像想要 apply :

select t.id, v.time, t.metadata1, t.metadata2
from t cross apply
     (values (a_time), (b_time), (c_time), (d_time)
     ) v(time)
order by v.time;

相关问题