Vertica SQL:忽略行,基于两个条件
Vertica SQL: Disregard rows, based on two conditions
我需要一个 where 条件来考虑遵循整个 table:
如果 ID(在 d 列中)存在 0,则排除 >0 的所有内容,如果 0 不存在,但存在 d = a 的行,则排除之前的所有内容..
在示例(案例 1)中,我想忽略第 1 行和第 2 行,在示例 2(案例 2)中,我想忽略第 1、2 行和第 3 行。
当前我有:where d <= 0 or d = a
) 但在案例 1 中这也是 returns 第 2 行,这是我不想要的。
row nr
ID
d
a
1
1
180
78
2
1
78
78
3
1
0
78
4
1
-67
78
5
1
-121
78
row nr
ID
d
a
1
2
180
148
2
2
171
148
3
2
170
148
4
2
148
148
5
2
-67
148
6
2
-121
148
这比您预期的要复杂一些。您将不得不使用带有 OLAP 函数的嵌套查询来检测分区中的每一行(由 id
的值定义)属于一个分区,其中至少有一行的值为 0 d
,然后在该嵌套查询之外过滤该事实,并且 d
的值为 0 或更大。这是案例 1.
在另一种情况下,您使用相同的嵌套查询来确定您只使用分区中 没有行 且 d
值为 0 的行,从那里开始,最简单的方法是使用 Vertica 的 MATCH()
子句来过滤掉由以下内容组成的行模式: d
等于 a
的行;我在查询中描述的任何行的零次、一次或多次出现,其模式为:(d_equal_a anyrow*)
.
这里是:
WITH
-- YOUR INPUT, don't use in query
indata(row_nr,ID,d,a) AS (
SELECT 1,1,180,78
UNION ALL SELECT 2,1,78,78
UNION ALL SELECT 3,1,0,78
UNION ALL SELECT 4,1,-67,78
UNION ALL SELECT 5,1,-121,78
UNION ALL SELECT 1,2,180,148
UNION ALL SELECT 2,2,171,148
UNION ALL SELECT 3,2,170,148
UNION ALL SELECT 4,2,148,148
UNION ALL SELECT 5,2,-67,148
UNION ALL SELECT 6,2,-121,148
)
-- end of your input, real query starts here, replace following comma with "WITH"
,
min_abs_d_eq_0 AS (
-- nested query with OLAP expression returning Boolean
SELECT
*
, (MIN(ABS(d)) OVER (PARTITION BY id) = 0) AS min_abs_d_eq_0
FROM indata
)
,
case1 AS (
SELECT
row_nr
, id
, d
, a
, 'no match clause' AS event_name -- these are based on the
, 0 AS pattern_id -- MATCH clause coming from
, 0 AS match_id -- the next CTE, "case2"
FROM min_abs_d_eq_0
WHERE min_abs_d_eq_0 AND d <= 0
)
,
case2 AS (
SELECT
row_nr
, id
, d
, a
, event_name()
, pattern_id()
, match_id()
FROM min_abs_d_eq_0
WHERE NOT min_abs_d_eq_0
MATCH (
PARTITION BY id ORDER BY row_nr
DEFINE
d_equal_a AS d = a
, anyrow AS true
PATTERN p AS (d_equal_a anyrow*)
)
)
SELECT * FROM case1
UNION ALL
SELECT * FROM case2
ORDER BY id,row_nr;
-- out row_nr | id | d | a | event_name | pattern_id | match_id
-- out --------+----+------+-----+-----------------+------------+----------
-- out 3 | 1 | 0 | 78 | no match clause | 0 | 0
-- out 4 | 1 | -67 | 78 | no match clause | 0 | 0
-- out 5 | 1 | -121 | 78 | no match clause | 0 | 0
-- out 4 | 2 | 148 | 148 | d_equal_a | 1 | 1
-- out 5 | 2 | -67 | 148 | anyrow | 1 | 2
-- out 6 | 2 | -121 | 148 | anyrow | 1 | 3
我需要一个 where 条件来考虑遵循整个 table:
如果 ID(在 d 列中)存在 0,则排除 >0 的所有内容,如果 0 不存在,但存在 d = a 的行,则排除之前的所有内容..
在示例(案例 1)中,我想忽略第 1 行和第 2 行,在示例 2(案例 2)中,我想忽略第 1、2 行和第 3 行。
当前我有:where d <= 0 or d = a
) 但在案例 1 中这也是 returns 第 2 行,这是我不想要的。
row nr | ID | d | a |
---|---|---|---|
1 | 1 | 180 | 78 |
2 | 1 | 78 | 78 |
3 | 1 | 0 | 78 |
4 | 1 | -67 | 78 |
5 | 1 | -121 | 78 |
row nr | ID | d | a |
---|---|---|---|
1 | 2 | 180 | 148 |
2 | 2 | 171 | 148 |
3 | 2 | 170 | 148 |
4 | 2 | 148 | 148 |
5 | 2 | -67 | 148 |
6 | 2 | -121 | 148 |
这比您预期的要复杂一些。您将不得不使用带有 OLAP 函数的嵌套查询来检测分区中的每一行(由 id
的值定义)属于一个分区,其中至少有一行的值为 0 d
,然后在该嵌套查询之外过滤该事实,并且 d
的值为 0 或更大。这是案例 1.
在另一种情况下,您使用相同的嵌套查询来确定您只使用分区中 没有行 且 d
值为 0 的行,从那里开始,最简单的方法是使用 Vertica 的 MATCH()
子句来过滤掉由以下内容组成的行模式: d
等于 a
的行;我在查询中描述的任何行的零次、一次或多次出现,其模式为:(d_equal_a anyrow*)
.
这里是:
WITH
-- YOUR INPUT, don't use in query
indata(row_nr,ID,d,a) AS (
SELECT 1,1,180,78
UNION ALL SELECT 2,1,78,78
UNION ALL SELECT 3,1,0,78
UNION ALL SELECT 4,1,-67,78
UNION ALL SELECT 5,1,-121,78
UNION ALL SELECT 1,2,180,148
UNION ALL SELECT 2,2,171,148
UNION ALL SELECT 3,2,170,148
UNION ALL SELECT 4,2,148,148
UNION ALL SELECT 5,2,-67,148
UNION ALL SELECT 6,2,-121,148
)
-- end of your input, real query starts here, replace following comma with "WITH"
,
min_abs_d_eq_0 AS (
-- nested query with OLAP expression returning Boolean
SELECT
*
, (MIN(ABS(d)) OVER (PARTITION BY id) = 0) AS min_abs_d_eq_0
FROM indata
)
,
case1 AS (
SELECT
row_nr
, id
, d
, a
, 'no match clause' AS event_name -- these are based on the
, 0 AS pattern_id -- MATCH clause coming from
, 0 AS match_id -- the next CTE, "case2"
FROM min_abs_d_eq_0
WHERE min_abs_d_eq_0 AND d <= 0
)
,
case2 AS (
SELECT
row_nr
, id
, d
, a
, event_name()
, pattern_id()
, match_id()
FROM min_abs_d_eq_0
WHERE NOT min_abs_d_eq_0
MATCH (
PARTITION BY id ORDER BY row_nr
DEFINE
d_equal_a AS d = a
, anyrow AS true
PATTERN p AS (d_equal_a anyrow*)
)
)
SELECT * FROM case1
UNION ALL
SELECT * FROM case2
ORDER BY id,row_nr;
-- out row_nr | id | d | a | event_name | pattern_id | match_id
-- out --------+----+------+-----+-----------------+------------+----------
-- out 3 | 1 | 0 | 78 | no match clause | 0 | 0
-- out 4 | 1 | -67 | 78 | no match clause | 0 | 0
-- out 5 | 1 | -121 | 78 | no match clause | 0 | 0
-- out 4 | 2 | 148 | 148 | d_equal_a | 1 | 1
-- out 5 | 2 | -67 | 148 | anyrow | 1 | 2
-- out 6 | 2 | -121 | 148 | anyrow | 1 | 3