我有一个非常大的数据集,我需要为每个可用的time_stamp选择特定的标签,但如果存在给定标签的多个time_stamps,我需要选择具有最新loadtimestamp的那个
这是我的数据集的简化版本:
|tag_name | value | time_stamp | loadtimestamp |
|:---------:|:-------:|:-----------------:|:-----------------:|
| TAG1 | 10 |2017-01-19 22:16:04|2017-01-19 22:49:58|
| TAG2 | 89 |2017-01-19 22:16:04|2017-01-19 22:49:58|
| TAG3 | 22 |2017-01-19 22:16:04|2017-01-19 22:49:58|
| TAG1 | 12 |2017-01-19 22:17:05|2017-01-19 22:49:58|
| TAG2 | 93 |2017-01-19 22:17:05|2017-01-19 22:49:58|
| TAG3 | 15 |2017-01-19 22:17:05|2017-01-19 22:49:58|
| TAG1 | 9 |2017-01-19 22:16:04|2017-01-22 12:29:12|
| TAG2 | 88 |2017-01-19 22:16:04|2017-01-22 12:29:12|
| TAG3 | 21 |2017-01-19 22:16:04|2017-01-22 12:29:12|
| TAG1 | 15 |2017-01-19 22:18:05|2017-01-19 22:49:58|
| TAG2 | 98 |2017-01-19 22:18:05|2017-01-19 22:49:58|
| TAG3 | 23 |2017-01-19 22:18:05|2017-01-19 22:49:58|
最初,我没有考虑loadtimestamp问题,我的查询如下:
select time_stamp,
MAX(Case when tag_name = 'TAG1' then value else NULL END) as "Tagname 1",
MAX(Case when tag_name = 'TAG2' then value else NULL END) as "Tagname 2",
MAX(Case when tag_name = 'TAG3' then value else NULL END) as "Tagname 3",
from "DATATABLE".calculated_data
group by time_stamp
我使用case语句,因为我需要一种方法来为数据集中的每个标记赋予特定的名称。
结果是在22:16:04,我有多个标签的结果/值。我的需要是每个tag / time_stamp只有一个值,而且它是具有最新loadtimestamp的值。
我已经看到了几个版本的查询试图提取最新日期,但在使用case语句时我找不到应用它的方法。
我尝试了几个带有子查询的版本,但我相信结果是每个时间找到一个标记,它查询整个数据集寻找相同的标记和time_stamp然后选择一个最新的loadtimestamp。由于我的数据集是大约5000万行,而我的结果表应该是~100万,这种方法是不可行的(说实话,我从来没有让它真正起作用)。我的最终方法需要进行一些优化,以便它可以在合理的时间内执行。
要明确我对SQL很新,有点超出我的深度,所以如果这是过于基本或可能不清楚,我道歉。我非常感谢有关这个问题的任何帮助或指示。
谢谢!
答案 0 :(得分:0)
select t.tag_name ,t.time_stamp from
(select tag_name ,time_stamp ,
row_number()over(partition by tag_name,time_stamp order by loadtimestamp
desc) as RN
from calculated_data)t
where t.RN=1
答案 1 :(得分:0)
卡皮尔的回答很有效。完整查询只需要约3分钟。
通过案例陈述,它最终看起来像这样:
select t.time_stamp,
MAX(Case when tag_name = 'TAG1' then value else NULL END) as "Tagname 1",
MAX(Case when tag_name = 'TAG2' then value else NULL END) as "Tagname 2",
MAX(Case when tag_name = 'TAG3' then value else NULL END) as "Tagname 3",
from
(select time_stamp, tag_name value,
row_number()over(partition by tag_name , time_stamp, value order by loadtimestamp
desc) as RN
from calculated_data) t
where t.RN = 1
group by t.time_stamp
order by t.time_stamp;