英文:
Find transitions from exact values SQL
问题
| 行号 | 类别 | 前一行号 | 前一类别 |
| ------ | ------- | ----------- | ---------- |
| 6 | Math | 7 | Other |
| 11 | Biology | 12 | Other |
| 15 | Biology | 16 | Other |
| 19 | Physics | 20 | Others |
英文:
There is a dataset. I would like to take first transitions from class not in (Other, Others) to class in (Other, Others)
| row_id | class |
| ------ | ------- |
| 1 | Math |
| 2 | Math |
| 3 | Math |
| 4 | Math |
| 5 | Math |
| 6 | Math |
| 7 | Other |
| 8 | Other |
| 9 | Other |
| 10 | Biology |
| 11 | Biology |
| 12 | Other |
| 13 | Other |
| 14 | Biology |
| 15 | Biology |
| 16 | Others |
| 17 | Others |
| 18 | Others |
| 19 | Physics |
| 20 | Others |
So the result will be :
| row_id | class | prev_row_id | prev_class |
| ------ | ------- | ----------- | ---------- |
| 6 | Math | 7 | Other |
| 11 | Biology | 12 | Other |
| 15 | Biology | 16 | Other |
| 19 | Physics | 20 | Others |
I have found how to detect LAST transition but not in history. I use PTRESTO.
答案1
得分: 1
可以在这里使用LEAD()
分析函数:
<!-- 语言: sql -->
WITH cte AS (
SELECT *, LEAD(class) OVER (ORDER BY row_id) AS lead_class,
LEAD(row_id) OVER (ORDER BY row_id) AS lead_row_id
FROM yourTable
)
SELECT
row_id,
class,
lead_row_id AS next_row_id,
lead_class AS next_class
FROM cte
WHERE class NOT IN ('Other', 'Others') AND
lead_class IN ('Other', 'Others')
ORDER BY row_id;
英文:
We can use the LEAD()
analytic function here:
<!-- language: sql -->
WITH cte AS (
SELECT *, LEAD(class) OVER (ORDER BY row_id) AS lead_class,
LEAD(row_id) OVER (ORDER BY row_id) AS lead_row_id
FROM yourTable
)
SELECT
row_id,
class,
lead_row_id AS next_row_id,
lead_class AS next_class
FROM cte
WHERE class NOT IN ('Other', 'Others') AND
lead_class IN ('Other', 'Others')
ORDER BY row_id;
答案2
得分: 0
可以自连接表,限制初始行不与其他行连接,并连接到其他行,使它们连续:
select t.row_id, t.class, th.row_id prev_row_id , th.class prev_class
from my_table t
join my_table th
on (th.row_id = t.row_id + 1 and th.class in ('Other', 'Others'))
where t.class not in ('Other', 'Others')
注意: 仅当ID连续时才有效
英文:
You can self join table limiting initial row to not others, and joind to other and them to be sequential:
select t.row_id, t.class, th.row_id prev_row_id , th.class prev_class
from my_table t
join my_table th
on (th.row_id = t.row_id + 1 and th.class in ('Other', 'Others'))
where t.class not in ('Other', 'Others')
*Caution: this will work only if id is continuous
答案3
得分: 0
你可以使用窗口函数。例如,lag
函数:
-- 样本数据
with dataset(row_id, class) as(
values (1, '数学'),
(2, '数学'),
(6, '数学'),
(7, '其他'),
(9, '其他'),
(10, '生物'),
(11, '生物'),
(12, '其他'),
(13, '其他'),
(14, '生物'),
(15, '生物'),
(16, '其他'),
(17, '其他'),
(18, '其他'),
(19, '物理'),
(20, '其他')
),
-- 查询部分
with_prev as(
SELECT *,
lag(row_id) OVER w AS prev_row_id,
lag(class) OVER w AS prev_class
FROM dataset
WINDOW w AS (ORDER BY row_id) -- Trino 允许共享窗口
)
select *
from with_prev
where prev_class not like '其他%' and class like '其他%'; -- 或者在 ('其他', '其他人') 中
输出:
row_id | class | prev_row_id | prev_class |
---|---|---|---|
7 | 其他 | 6 | 数学 |
12 | 其他 | 11 | 生物 |
16 | 其他人 | 15 | 生物 |
20 | 其他人 | 19 | 物理 |
英文:
You can use window functions. For example lag
:
-- sample data
with dataset(row_id, class) as(
values (1, 'Math'),
(2, 'Math'),
(6, 'Math'),
(7, 'Other'),
(9, 'Other'),
(10, 'Biology'),
(11, 'Biology'),
(12, 'Other'),
(13, 'Other'),
(14, 'Biology'),
(15, 'Biology'),
(16, 'Others'),
(17, 'Others'),
(18, 'Others'),
(19, 'Physics'),
(20, 'Others')
),
-- query parts
with_prev as(
SELECT *,
lag(row_id) OVER w AS prev_row_id,
lag(class) OVER w AS prev_class
FROM dataset
WINDOW w AS (ORDER BY row_id) -- Trino allows sharing window
)
select *
from with_prev
where prev_class not like 'Other%' and class like 'Other%'; -- or in ('Other', 'Others')
Output:
row_id | class | prev_row_id | prev_class |
---|---|---|---|
7 | Other | 6 | Math |
12 | Other | 11 | Biology |
16 | Others | 15 | Biology |
20 | Others | 19 | Physics |
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论