在符合选择条件的行之前选择n行

时间:2019-12-09 19:13:14

标签: sql hadoop pyspark-sql

我有一条来自生产线的大型流程数据表,其中包含产品在Hadoop数据湖中创建过程中要经历的许多步骤。在某些时候,我有兴趣找出在进行某个过程之前的N个步骤中发生了什么。

我可以编写一个选择查询,该查询返回与我可以识别的进程相对应的行,但是如何(我应该)在满足实际选择查询的那一行之前返回N行呢?

我想知道是否可以在SQL / pyspark中做这样的事情,是否应该这样做,或者在选择包含我想要的信息的更大数据集之后是否应该在python中做这样的事情并使用python过滤掉我需要的位。

示例表结构:

|Col 1 | Col 2 | Col 3| Col 4  |
|A     | 1     | One  | Date 1 |
|C     | 1     | Two  | Date 2 |
|B     | 1     | One  | Date 1 |
|C     | 2     | Two  | Date 2 |
|C     | 1     | Three| Date 3 |
|D     | 2     | Four | Date 1 |
|E     | 1     | Five | Date 5 |

SELECT * FROM Table1
WHERE COL 1 = "C" and COL 3 = "Three"
ORDER BY COL 4, Col 2

会返回什么

|Col 1 | Col 2 | Col 3| Col 4  |
|C     | 1     | Three| Date 3 |

我想退还什么

|Col 1 | Col 2 | Col 3| Col 4  |
|C     | 1     | One  | Date 2 |
|C     | 2     | Two  | Date 2 |
|C     | 1     | Three| Date 3 |

N = 2以上,但N应该是可变的。如果可以在SQL中实现,那么我真的很感兴趣这是否应该在SQL中完成,或者最好在之后的代码中完成。我可以看到双方的论点,但需要一些外部意见。

编辑:建议的两种方法似乎都依赖于我之前提供的结构,其中第2列是递增值。当我使用第2列和数字作为虚拟值时,这会产生误导。现在,我用两列更新了表,该列实际上显示了表的正确排序方式。首先是包含日期时间戳的列,其次是包含整数的列。

该表是Hadoop数据湖中的表,因此建议的解决方案应提供可以在该环境中执行的SQL。

编辑2:显而易见,行本身不一定是连续的,所以我不希望最后N行,而是想要也满足某个谓词的最后N行。在上面的示例中,谓词应为Col2 =“ C”。

2 个答案:

答案 0 :(得分:1)

您可以使用row_number()函数,如下所示:

Declare @n int = 3

SELECT *
FROM (
   select Col1,Col2,Col3,
          Row_Number() over (ORDER BY Col2 ASC) as RowOrder
   from table1
) x
where x.RowOrder <= @n

答案 1 :(得分:1)

您可以使用连续计数:

SELECT *
FROM (SELECT t1.*,
             SUM(CASE WHEN COL1 = 'D' AND COL2 = 'Three THEN 1 ELSE 0 END)  OVER (ORDER BY col2 ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING) as cnt_special
      FROM Table1 t1
WHERE cnt_special > 0;

或者,您可以使用窗口函数来识别col2值。如果您希望偏移量是逻辑的(即基于col2中的),而不是物理的(即行数),则此方法有效:

SELECT *
FROM (SELECT t1.*,
             MAX(CASE WHEN COL1 = 'D' AND COL2 = 'Three THEN col2 END)  OVER (ORDER BY col2) as special_col2
      FROM Table1 t1
WHERE col2 <= special_col2 and col2 >= special_col2 - 2