有没有办法基于前一行查找特定值的行?

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

Is there a way to find rows of a certain value based on the previous row?

问题

我想要选择在表中具有特定值的行,但前一行也必须包括特定值。例如,

ID column1 column2
1 S 日期
1 T 日期
1 J 日期
1 C 日期
2 D 日期
2 Q 日期
2 L 日期
2 J 日期
2 C 日期
3 L 日期
3 T 日期
3 T 日期
3 C 日期

我只想选择在column2中具有'C'状态的ID,当前一个状态是'T'时。

是否可以做到这一点?

英文:

I'm trying to search in a table rows that have a certain value but the previous row has to include specific values as well. Ex.

ID column1 column2
1 S Date
1 T Date
1 J Date
1 C Date
2 D Date
2 Q Date
2 L Date
2 J Date
2 C Date
3 L Date
3 T Date
3 T Date
3 C Date

I would just want to select on IDs that have 'C' status in column 2 when the status immediately before is 'T'.

Is it possible to do this?

答案1

得分: 0

从Oracle 12版本开始,您可以使用MATCH_RECOGNIZE

  1. SELECT id, column1, column2
  2. FROM table_name
  3. MATCH_RECOGNIZE (
  4. PARTITION BY id
  5. ORDER BY something_that_orders_the_rows
  6. ALL ROWS PER MATCH
  7. PATTERN ( {- status_t -} status_c)
  8. DEFINE
  9. status_t AS column1 = 'T',
  10. status_c AS column1 = 'C'
  11. );

或者,在早期版本中,您可以使用LAG分析函数:

  1. SELECT id, column1, column2
  2. FROM (
  3. SELECT id, column1, column2,
  4. LAG(column1) OVER (PARTITION BY id ORDER BY something_that_orders_the_rows) AS prev_c1
  5. FROM table_name t
  6. )
  7. WHERE column1 = 'C'
  8. AND prev_c1 = 'T';

对于示例数据:

  1. CREATE TABLE table_name (ID, column1, column2, something_that_orders_the_rows) AS
  2. SELECT 1, 'S', 'Date', 1 FROM DUAL UNION ALL
  3. SELECT 1, 'T', 'Date', 2 FROM DUAL UNION ALL
  4. SELECT 1, 'J', 'Date', 3 FROM DUAL UNION ALL
  5. SELECT 1, 'C', 'Date', 4 FROM DUAL UNION ALL
  6. SELECT 2, 'D', 'Date', 1 FROM DUAL UNION ALL
  7. SELECT 2, 'Q', 'Date', 2 FROM DUAL UNION ALL
  8. SELECT 2, 'L', 'Date', 3 FROM DUAL UNION ALL
  9. SELECT 2, 'J', 'Date', 4 FROM DUAL UNION ALL
  10. SELECT 2, 'C', 'Date', 5 FROM DUAL UNION ALL
  11. SELECT 3, 'L', 'Date', 1 FROM DUAL UNION ALL
  12. SELECT 3, 'T', 'Date', 2 FROM DUAL UNION ALL
  13. SELECT 3, 'T', 'Date', 3 FROM DUAL UNION ALL
  14. SELECT 3, 'C', 'Date', 4 FROM DUAL;

两者的输出都是:

ID COLUMN1 COLUMN2
3 C Date

fiddle

英文:

From Oracle 12, you can use MATCH_RECOGNIZE:

  1. SELECT id, column1, column2
  2. FROM table_name
  3. MATCH_RECOGNIZE (
  4. PARTITION BY id
  5. ORDER BY something_that_orders_the_rows
  6. ALL ROWS PER MATCH
  7. PATTERN ( {- status_t -} status_c)
  8. DEFINE
  9. status_t AS column1 = 'T',
  10. status_c AS column1 = 'C'
  11. );

or, in earlier versions, you can use the LAG analytic function:

  1. SELECT id, column1, column2
  2. FROM (
  3. SELECT id, column1, column2,
  4. LAG(column1) OVER (PARTITION BY id ORDER BY something_that_orders_the_rows) AS prev_c1
  5. FROM table_name t
  6. )
  7. WHERE column1 = 'C'
  8. AND prev_c1 = 'T';

Which, for the sample data:

  1. CREATE TABLE table_name (ID, column1, column2, something_that_orders_the_rows) AS
  2. SELECT 1, 'S', 'Date', 1 FROM DUAL UNION ALL
  3. SELECT 1, 'T', 'Date', 2 FROM DUAL UNION ALL
  4. SELECT 1, 'J', 'Date', 3 FROM DUAL UNION ALL
  5. SELECT 1, 'C', 'Date', 4 FROM DUAL UNION ALL
  6. SELECT 2, 'D', 'Date', 1 FROM DUAL UNION ALL
  7. SELECT 2, 'Q', 'Date', 2 FROM DUAL UNION ALL
  8. SELECT 2, 'L', 'Date', 3 FROM DUAL UNION ALL
  9. SELECT 2, 'J', 'Date', 4 FROM DUAL UNION ALL
  10. SELECT 2, 'C', 'Date', 5 FROM DUAL UNION ALL
  11. SELECT 3, 'L', 'Date', 1 FROM DUAL UNION ALL
  12. SELECT 3, 'T', 'Date', 2 FROM DUAL UNION ALL
  13. SELECT 3, 'T', 'Date', 3 FROM DUAL UNION ALL
  14. SELECT 3, 'C', 'Date', 4 FROM DUAL;

Both output:

ID COLUMN1 COLUMN2
3 C Date

fiddle

huangapple
  • 本文由 发表于 2023年2月9日 00:46:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/75389031.html
匿名

发表评论

匿名网友

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

确定