SQL / Teradata:返回连续行中的值相同的记录

时间:2016-09-01 13:55:08

标签: sql grouping teradata

我的数据集如下:

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

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

我使用Teradata,但如果有人为另一个引擎提供SQL解决方案,我通常可以设法翻译它。

谢谢。

2 个答案:

答案 0 :(得分:2)

你需要查看上一行/下一行并检查它是否没有改变:

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不会强制执行,因此您必须重写它。

答案 1 :(得分:0)

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

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 Server。

更简单的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