无法在sql中正确使用滞后函数

时间:2017-04-19 23:43:49

标签: sql oracle lag

我已经从多个表创建了一个表,如下所示:

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,因此它将在“重复”列中得到1,但是在行4中,custid 1出现L1 = 1,因此它将得到值as)。

顺便说一下,表格没有订购(如我所示)。

我正在尝试如下:

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

但这不是给出输出而是给出空结果。

3 个答案:

答案 0 :(得分:0)

我认为您需要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;

答案 1 :(得分:0)

这也可以在没有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;

答案 2 :(得分:0)

只需使用count(*)作为分析函数即可完成。不需要案例表达或自联接。该查询甚至可以跨支持分析功能的数据库移植:

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