我有一条来自生产线的大型流程数据表,其中包含产品在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”。
答案 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