我认为我非常了解SQL,直到我想创建看似简单的东西:
我想必须有一些基本的聚合函数允许在Vertica中执行此操作,但这是我在SQL中可以提出的最好的,而且我真的不喜欢我设法提出的 - 特别是对于大量数据,这种方法非常糟糕,因为它会消耗大量的内存(请注意CROSS JOIN野兽)。
输入数据:
项目表(重复的id,created_at)
CREATE TABLE items(id int, created_at timestamp);
INSERT INTO items(id, created_at) VALUES (1, '2016-01-02 00:00:00');
INSERT INTO items(id, created_at) VALUES (1, '2016-01-02 00:01:01');
INSERT INTO items(id, created_at) VALUES (2, '2016-01-02 00:05:10');
INSERT INTO items(id, created_at) VALUES (2, '2016-01-02 00:05:12');
INSERT INTO items(id, created_at) VALUES (3, '2016-01-02 00:05:01');
INSERT INTO items(id, created_at) VALUES (3, '2016-01-02 00:05:04');
INSERT INTO items(id, created_at) VALUES (3, '2016-01-02 00:05:30');
INSERT INTO items(id, created_at) VALUES (3, '2016-01-02 00:02:05');
INSERT INTO items(id, created_at) VALUES (3, '2016-01-02 00:20:02');
预期结果:
我的SQL查询版本:
(我现在真的很惭愧......)
SELECT
a.id,
sum(a.count) AS total_count,
agg_concatenate(a.count||',') AS histogram
FROM (
SELECT
i.id,
times.ts,
nvl(counts.count,0) AS count
FROM (
SELECT ts FROM (
SELECT '2016-01-02 00:00:00'::TIMESTAMP AS tm
UNION ALL
SELECT '2016-01-02 00:20:00'::TIMESTAMP AS tm
) t
TIMESERIES ts AS '1 minute' OVER (ORDER BY tm)) times
CROSS JOIN (
SELECT DISTINCT id FROM items
) i
LEFT OUTER JOIN (
SELECT
time_slice(created_at, 1, 'MINUTE') AS ts,
id,
count(*) AS count
FROM
items
GROUP BY
1,2) counts ON counts.ts=times.ts AND counts.id=i.id
ORDER BY 1,2
) a
GROUP BY
a.id
ORDER BY
2 DESC;
考虑的其他可能性
当然有一种替代方法可以用Java,C ++或其他语言编写自定义Vertica用户定义扩展,但在此之前,我真的想确保我没有错过一些简单的解决方案,如何做到这一点。 / p>
Vertica是一种数据库平台,人们会期望这样的东西存在,也许我在阅读手册时不够小心......
如果您是Vertica的专家或者在普通SQL中知道更好的解决方案,那么很高兴找到它。 即使你知道现有的UDX,也会有所帮助。主要的 - 我希望这个数据尽可能接近数据计算。
谢谢!
Maris的
答案 0 :(得分:0)
这看起来不错。我不知道你的直方图领域有任何优雅的解决方法:
agg_concatenate(a.count||',')
主要内容 - 我希望尽可能接近数据计算。
如果需要,我会在Excel或SQL之外进行这种连接,但我知道必须对数据处理的位置有特殊限制。
查询的性能是否真的很慢,无法满足您的需求?