SQL习题
SQL如何找出同一个ID values中连续小于 60的记录。
比如标蓝色的,中间有一个大于60的就不算连续。2次或者以上就算连续;
table: product_id_value
index_id | product_id | date | id_values | time_count |
---|---|---|---|---|
1 | 01 | 2013/1/7 | 61 | 1 |
2 | 01 | 2013/1/8 | 57 | 2 |
3 | 01 | 2014/5/1 | 60 | 3 |
4 | 01 | 2014/5/2 | 58 | 4 |
5 | 01 | 2014/5/3 | 61 | 5 |
6 | 01 | 2014/5/4 | 46 | 6 |
7 | 02 | 2013/1/7 | 58 | 1 |
8 | 02 | 2013/1/8 | 54 | 2 |
9 | 02 | 2014/5/1 | 57 | 3 |
10 | 02 | 2014/5/2 | 69 | 4 |
11 | 02 | 2014/5/3 | 54 | 5 |
12 | 02 | 2014/5/4 | 77 | 6 |
13 | 02 | 2015/8/1 | 54 | 7 |
14 | 02 | 2015/8/2 | 58 | 8 |
上图中输出数据为
index | product_id | date | values | time_count |
---|---|---|---|---|
7 | 02 | 2013/1/7 | 58 | 1 |
8 | 02 | 2013/1/8 | 54 | 2 |
9 | 02 | 2014/5/1 | 57 | 3 |
13 | 02 | 2015/8/1 | 54 | 7 |
14 | 02 | 2015/8/2 | 58 | 8 |
点击查看
--方案一
--注意事项
--1:自关联好像有字段相同的问题;
--2:需要union处理全部满足条件的数据
with table_a as
(SELECT
*
from
(
(select *
from product_id_value) a
left join
(select
index_id as b_index_id,
product_id as b_product_id,
`date` as b_date_id,
id_values as b_id_values,
time_count as b_time_count
from product_id_value) b
on a.product_id=b.b_product_id and a.time_count=b.b_time_count-1)t
where
id_values<60 and b_id_values<60)
select
index_id ,
product_id ,
`date` ,
id_values ,
time_count
FROM
table_a
union
select
b_index_id,
b_product_id,
b_date_id,
b_id_values,
b_time_count
FROM
table_a
--方案二
--注意事项:
--1:rn2和rn3数值一样,校验函数可以用负值
--2:考虑排名第一位和最后一位的判断问题
SELECT
*
from
(select
*,
lead(id_values,1,0) over(partition by product_id order by `date`) as rn1,
lag(id_values,1,0) over(partition by product_id order by `date`) as rn2,
lead(id_values,-1,0) over(partition by product_id order by `date`) as rn3
from product_id_value) t
where
(id_values<60 and rn1<60 and rn1<>0 ) or (id_values<60 and rn2<60 and rn2<>0)
方案三:
with t1 as (
select
*
#求出差值,因为id一定不会相同,所以使用最熟悉的rank就好
index_id-rank() over(order by index_id) rk
from stadium
where people < 60
)
select
*
from t1
#where条件过滤出条数大于2的
where rk in (
select rk from t1 group by rk having count(1) >= 2);