SQL/Teradata: Return 条连续行值相同的记录

SQL/Teradata: Return records where value in consecutive rows is the same

我的数据集如下所示:

ID        date     emp_num    loc
1111     5/2/16    111111     Brooklyn
1112     5/3/16    222222     Detroit
1113     5/3/16    333333     San Diego
1114     5/2/16    333333     Orlando
1115     5/5/16    333333     Brooklyn
1116     5/7/16    111111     Orlando

在这种情况下,我想 return 记录 1113、1114 和 1115,因为连续行(按 ID 排序)中的 emp_num 是相同的。

我使用 Teradata,但如果有人有其他引擎的 SQL 解决方案,我通常可以设法翻译它。

谢谢。

首先,获取按 id 列排序并按 emp_num 分区并按 id 列排序的行号差异。这会将 emp_num 分类。然后,获取其中有多个成员的组(这意味着有连续的行具有相同的 emp_num 值)。最后 select 这些组所需的列。

WITH x AS (SELECT
  *,
  ROW_NUMBER() OVER (ORDER BY id) - ROW_NUMBER() OVER (PARTITION BY emp_num ORDER BY id) grp
FROM t),
grpsneeded
AS (SELECT
  grp
FROM x
GROUP BY grp
HAVING COUNT(*) > 1)
SELECT
  id,
  dt,
  emp_num
FROM x
WHERE grp IN (SELECT
  grp
FROM grpsneeded)

Sample Demo

此解决方案适用于 SQL 服务器。

更简单的 SQL 解决方案是使用 leadlag 函数。正如@dnoeth 所指出的,Teradata 不支持这些功能。但是,这可能对其他数据库引擎有用。

select id, dt , emp_num from (
select *
,lead(emp_num) over(order by id) nxt
,lag(emp_num) over(order by id) prev
from t
) x
where coalesce(nxt,0) = emp_num or coalesce(prev,0) = emp_num

您需要查看 previous/next 行并检查它是否未更改:

SELECT * 
FROM tab
QUALIFY 
   MIN(emp_num) --previous row
   OVER (ORDER BY ID
         ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) = emp_num
OR
   MIN(emp_num) -- next row
   OVER (ORDER BY ID
         ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING) = emp_num

在标准 SQL 中,这将是 LAG/LEAD 的任务,但 Teradata 不会阻止它,因此您必须重写它。