我已经从多个表创建了一个表,如下所示:
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;
但这不是给出输出而是给出空结果。
答案 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。