无法在 sql 中正确使用滞后功能

Unable to use lag function correctly in sql

我从多个 table 创建了一个 table,如下所示:

Week | Cid | CustId | L1
10 | 1 | 1 | 2
10 | 2 | 1 | 2
10 | 5 | 1 | 2
10 | 4 | 1 | 1
10 | 3 | 2 | 1
4  | 6 | 1 | 2
4  | 7 | 1 | 2

我希望输出为:

Repeat
0
1
1
0
0
0
1

所以,基本上我想要的是每个星期,如果一个人(custid)再次以相同的 L1 进来,那么 Repeat 列中的值应该变为 1,否则为 0(就像,在这里,在第 2 行和第 3 行中,custid 1 再次出现 L1=2,因此它将在 "Repeat" 列中获得 1,但是在第 4 行中,custid 1 出现了 L1=1,因此它将获得值作为 ).

顺便说一句,table 没有排序(如我所示)。

我正在尝试按如下方式进行:

select t.*,
lag(0, 1, 0) over (partition by week, custid, L1 order by cid) as repeat
from
table;

但这并没有给出输出,而是给出了空结果。

我认为您需要 case,但我会为此使用 row_number()

select t.*,
       (case when row_number() over (partition by week, custid, l1 order by cid) = 1
             then 0 else 1
        end) as repeat
from table;

这也可以在没有 Window 函数的情况下进行计算,但可以通过以下方式进行自连接:

SELECT a.week, a.cid, a.custid, a.l1,
       CASE WHEN b IS NULL THEN 1 ELSE 0 END AS repeat
FROM mytable a NATURAL LEFT JOIN
     (SELECT week, min(cid) AS cid, custid, l1 FROM mytable
      GROUP BY week,custid,l1) b
ORDER BY week DESC, custid, l1 DESC, cid;

它可以简单地通过使用 count(*) 作为解析函数来完成。不需要 case 表达式或自连接。该查询甚至可以跨支持分析功能的数据库移植:

SELECT cust.*, least(count(*) 
        OVER (PARTITION BY Week, CustId, L1 ORDER BY Cid
        ROWS UNBOUNDED PRECEDING) - 1, 1) repeat
FROM cust ORDER BY Week DESC, custId, L1 DESC;

对您的数据执行查询会产生以下输出(最后一行是重复行):

Week | Cid | CustId | L1 | repeat
10  1   1   2   0
10  2   1   2   1
10  5   1   2   1
10  4   1   1   0
10  3   2   1   0
4   6   1   2   0
4   7   1   2   1

已在 Oracle 11g 和 PostgreSQL 9.4 上测试。请注意,第二个 ORDER BY 是可选的。有关详细信息,请参阅 Oracle Language Reference, Analytic Functions