从确切的数值找过渡 SQL

huangapple go评论60阅读模式
英文:

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 (&#39;Other&#39;, &#39;Others&#39;) AND
      lead_class IN (&#39;Other&#39;, &#39;Others&#39;)
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 (&#39;Other&#39;, &#39;Others&#39;))
 where t.class not in (&#39;Other&#39;, &#39;Others&#39;)

*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,  &#39;Math&#39;),
        (2,  &#39;Math&#39;),
        (6,  &#39;Math&#39;),
        (7,  &#39;Other&#39;),
        (9,  &#39;Other&#39;),
        (10, &#39;Biology&#39;),
        (11, &#39;Biology&#39;),
        (12, &#39;Other&#39;),
        (13, &#39;Other&#39;),
        (14, &#39;Biology&#39;),
        (15, &#39;Biology&#39;),
        (16, &#39;Others&#39;),
        (17, &#39;Others&#39;),
        (18, &#39;Others&#39;),
        (19, &#39;Physics&#39;),
        (20, &#39;Others&#39;)
),

-- 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 &#39;Other%&#39; and class like &#39;Other%&#39;; -- or in (&#39;Other&#39;, &#39;Others&#39;) 

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

huangapple
  • 本文由 发表于 2023年3月31日 20:42:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/75898668.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定