【发布时间】:2021-06-28 21:49:57
【问题描述】:
收到 cmets 后,我将用所需数据重新表述这个问题。
参考:SQL query to exclude some records from the output
Vertica 解析函数:https://www.vertica.com/blog/analytic-queries-vertica/
表 1:
create table etl_group_membership
(
group_item_id int not null,
member_item_id int not null
);
INSERT INTO etl_group_membership (group_item_id, member_item_id) VALUES (335640, 117722);
INSERT INTO etl_group_membership (group_item_id, member_item_id) VALUES (335640, 104151);
INSERT INTO etl_group_membership (group_item_id, member_item_id) VALUES (335640, 5316);
INSERT INTO etl_group_membership (group_item_id, member_item_id) VALUES (335641, 117723);
INSERT INTO etl_group_membership (group_item_id, member_item_id) VALUES (335641, 104152);
INSERT INTO etl_group_membership (group_item_id, member_item_id) VALUES (335641, 5317);
INSERT INTO etl_group_membership (group_item_id, member_item_id) VALUES (335642, 117724);
INSERT INTO etl_group_membership (group_item_id, member_item_id) VALUES (335642, 104153);
INSERT INTO etl_group_membership (group_item_id, member_item_id) VALUES (335642, 5318);
表 2:
create table v_poll_item
(
device_item_id int not null,
item_id int not null
);
INSERT INTO v_poll_item (device_item_id, item_id) VALUES (117722, 273215);
INSERT INTO v_poll_item (device_item_id, item_id) VALUES (117722, 117936);
INSERT INTO v_poll_item (device_item_id, item_id) VALUES (117722, 117873);
INSERT INTO v_poll_item (device_item_id, item_id) VALUES (117722, 123305);
INSERT INTO v_poll_item (device_item_id, item_id) VALUES (104151, 240006);
INSERT INTO v_poll_item (device_item_id, item_id) VALUES (104151, 240005);
INSERT INTO v_poll_item (device_item_id, item_id) VALUES (104151, 239415);
INSERT INTO v_poll_item (device_item_id, item_id) VALUES (104151, 239414);
INSERT INTO v_poll_item (device_item_id, item_id) VALUES (5316, 118310);
INSERT INTO v_poll_item (device_item_id, item_id) VALUES (5316, 130627);
INSERT INTO v_poll_item (device_item_id, item_id) VALUES (5316, 298564);
INSERT INTO v_poll_item (device_item_id, item_id) VALUES (5316, 118311);
表 3:注意 im_utilization 也可以为 NULL
create table nrm_cpustats_rate
(
item_id int not null,
tstamp datetime not null,
im_utilization float,
);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (273215, '2021-06-28 19:55:00.000000', 2);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (273215, '2021-06-27 23:35:00.000000', 24);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (273215, '2021-06-26 14:05:00.000000', 27);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (273215, '2021-06-25 09:05:00.000000', 29);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (117936, '2021-06-28 19:30:00.000000', 17);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (117936, '2021-06-28 19:15:00.000000', 35);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (117936, '2021-06-28 19:05:00.000000', 50);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (117936, '2021-06-27 05:45:00.000000', 89);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (117936, '2021-06-25 09:20:00.000000', 37);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (117936, '2021-06-25 09:10:00.000000', 51);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (117936, '2021-06-25 08:50:00.000000', 90);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (118310, '2021-06-23 04:10:00.000000', 51);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (118310, '2021-06-23 03:15:00.000000', 48);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (118310, '2021-06-22 22:20:00.000000', 19);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (239414, '2021-06-22 17:10:00.000000', 11);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (239414, '2021-06-22 16:30:00.000000', 37);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (239414, '2021-06-22 16:35:00.000000', 38);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (239414, '2021-06-28 18:45:00.000000', 74);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (239414, '2021-06-28 18:48:00.000000', 76);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (239414, '2021-06-28 18:50:00.000000', 77);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (118311, '2021-06-28 00:40:00.000000', 29);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (118311, '2021-06-23 22:30:00.000000', 37);
INSERT INTO nrm_cpustats_rate (item_id, tstamp, im_utilization) VALUES (118311, '2021-06-23 22:25:00.000000', 92);
要获取组中的设备项 ID:
SELECT member_item_id FROM etl_group_membership WHERE group_item_id = 335640;
从检索到的设备item id列表中,获取item_ids列表:
SELECT item_id FROM v_poll_item WHERE device_item_id IN (<devices retrieved from previous query>);
输入:
- 两个时间范围:昨天到 7 天前 (
AND tstamp > '2021-06-22 00:00:00.000000'AND tstamp <= '2021-06-28 23:59:59.000000') - 组号:335640
- breach_threshold:25
- 每天最少违规次数:2
预期输出:
违反意味着 im_utilization >= 25
仅选择在给定日期内 count_of_breached >= 2 的记录 也就是说,item_id 为 273215 的记录被排除在外,因为即使违规次数 (>= 25) 为 2,但每天只有一个
device_item_id | item_id | count_of_breach | date_when_breached | max_utilization | max_utilization_tstamp
=====================================================================================================================
117722 | 117936 | 2 | 2021-06-28 | 90 | 2021-06-25 08:50:00.000000
117722 | 117936 | 3 | 2021-06-25 | 90 | 2021-06-25 08:50:00.000000
5316 | 118310 | 2 | 2021-06-23 | 51 | 2021-06-23 04:10:00.000000
5316 | 118311 | 2 | 2021-06-23 | 92 | 2021-06-23 22:25:00.000000
104151 | 239414 | 2 | 2021-06-22 | 77 | 2021-06-28 18:50:00.000000
104151 | 239414 | 3 | 2021-06-28 | 77 | 2021-06-28 18:50:00.000000
即使无法编写单个 SQL 查询来产生此输出,也可以建议两个优化查询。 @marcothesane 指出,即使是 query 也可以用更好的方式编写每日违规行为。
更新:
这个查询对我有用,可以在最大 im_utlization 和 tstamp 为最大值时找到它。我不确定为什么我必须在两个地方使用时间戳范围!
SELECT t.item_id, t.tstamp, t.im_utilization
FROM (
SELECT item_id, MAX(im_utilization) AS max_cpu
FROM nrm_cpustats_rate
WHERE item_id IN (SELECT item_id from v_poll_item WHERE device_item_id IN (SELECT item_id FROM v_poll_item WHERE device_item_id IN (117722, 104151, 5316)))
AND tstamp > '2021-06-22 00:00:00.000000
AND tstamp <= '2021-06-28 23:59:59.000000'
GROUP BY item_id
) AS m
INNER JOIN nrm_cpustats_rate AS t
ON t.item_id = m.item_id
AND t.im_utilization = m.max_cpu
AND tstamp > '2021-06-22 00:00:00.000000
AND tstamp <= '2021-06-28 23:59:59.000000'
ORDER BY 1, 2 DESC, 3 DESC
【问题讨论】:
-
请用适当的 DBMS 标记您的问题。我看到很多 SQL Server 的无效语法。
-
我标记了它。但是我认为如果我们去掉日期/时间相关的函数,SQL Server 的语法应该也是一样的。
-
我几乎可以肯定你可以比你想出的更简化你的初始查询。但我不能尝试,因为您不提供输入数据。您如何分别获得 20,17 和 19 的
max?您可以从中间结果中粘贴一堆行吗?我认为 OLAP 函数的一些巧妙用法会有所帮助。但我不能这样尝试...... -
我编辑了问题以使问题陈述更加详细。请看看现在这是否有意义。
-
请提供表的创建语句,插入语句以获得足够的数据来说明需求和期望的输出。