sql--7天内(含当天)购买次数超过3次(含),且近7天的购买金额超过1000的用户

背景

有一张用户购买记录表.现在我们需要找出所有的特殊用户.特殊用户的定义如下:
在当前购买时间的近7天内(含当天)购买次数超过3次(含),且近7天的购买金额超过1000的用户即为特殊用户.

数据

--创建测试表
create table aaa001
(
user_id int,
buy_date varchar(20),
amount int
)
;

--插入测试数据(102和104为特殊用户)
insert into  aaa001 (user_id,buy_date,amount) values (101,'2021-01-01',1000);
insert into  aaa001 (user_id,buy_date,amount) values(101,'2021-01-02',2000);
insert into  aaa001 (user_id,buy_date,amount) values(102,'2021-10-01',10);
insert into  aaa001 (user_id,buy_date,amount) values(102,'2021-10-02',700);
insert into  aaa001 (user_id,buy_date,amount) values(102,'2021-10-07',200);
insert into  aaa001 (user_id,buy_date,amount) values(103,'2021-11-07',500);
insert into  aaa001 (user_id,buy_date,amount) values(103,'2021-11-08',500);
insert into  aaa001 (user_id,buy_date,amount) values(103,'2021-11-20',500);
insert into  aaa001 (user_id,buy_date,amount) values(104,'2021-03-01',10);
insert into  aaa001 (user_id,buy_date,amount) values(104,'2021-03-05',200);
insert into  aaa001 (user_id,buy_date,amount) values(104,'2021-03-09',800);
insert into  aaa001 (user_id,buy_date,amount) values(104,'2021-03-09',800);
insert into  aaa001 (user_id,buy_date,amount) values(105,'2021-05-01',1);
insert into  aaa001 (user_id,buy_date,amount) values(105,'2021-05-10',2);

解决方案

自查询 -


---查询sql
select
*
from aaa001
order by user_id ,buy_date 
;
select user_id, sum(cnt) as cnt,sum(money) as money
from 
(select t1.user_id,t1.buy_date,t1.money,sum(t2.cnt) as cnt
from 
(select user_id,buy_date,count(*) as cnt,sum(amount)as money  from aaa001 group by user_id,buy_date)t1 
left join 
(select user_id,buy_date,count(*) as cnt,sum(amount)as money  from aaa001 group by user_id,buy_date)t2 
on t1.user_id = t2.user_id
and str_to_date(t2.buy_date, '%Y-%m-%d %H') >str_to_date(t1.buy_date, '%Y-%m-%d %H')
and  str_to_date(t2.buy_date, '%Y-%m-%d %H') <= date_add(t1.buy_date,INTERVAL 7 DAY) 
group by t1.user_id,t1.buy_date,t1.money)a 
group by user_id 
having sum(cnt ) >=3 and sum(money) >=1000;

开窗

---sql逻辑
select
distinct user_id
from
(
 select
  user_id
  ,buy_date
  ,count(1) over(PARTITION by user_id order by datediff(buy_date,'2021-01-01') RANGE between 6 PRECEDING and CURRENT row) as cnt
  ,sum(amount) over(PARTITION by user_id order by datediff(buy_date,'2021-01-01') RANGE between 6 PRECEDING and CURRENT row) as amount
 from test.aaa001
)t1
where cnt>=3 and amount>1000
好的,以下是一个简单的例子: 假设有一个用户充值卡的余额为50元,每消费1元钱,需要使用锁来保证同一时刻只能有一个线程进行充值或者消费操作,从而避免数据脏读问题的发生。 首先定义一个账户类Account,其中包余额balance和对余额进行充值和消费的方法deposit和withdraw: ```java public class Account { private int balance; public Account(int balance) { this.balance = balance; } // 充值 public synchronized void deposit(int amount) { balance += amount; } // 消费 public synchronized void withdraw(int amount) { if (balance >= amount) { balance -= amount; } } public int getBalance() { return balance; } } ``` 然后定义一个模拟消费的线程类ConsumerThread,每隔0.001秒就消费1元钱,循环执行50: ```java public class ConsumerThread extends Thread { private Account account; public ConsumerThread(Account account) { this.account = account; } @Override public void run() { for (int i = 0; i < 50; i++) { try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } account.withdraw(1); } } } ``` 最后在主函数中创建一个账户对象和两个模拟消费的线程对象: ```java public class Main { public static void main(String[] args) throws InterruptedException { Account account = new Account(50); ConsumerThread thread1 = new ConsumerThread(account); ConsumerThread thread2 = new ConsumerThread(account); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println("余额:" + account.getBalance()); } } ``` 运行程序,输出结果为: ``` 余额:0 ``` 可以看到,由于使用了锁来保证同一时刻只能有一个线程对账户进行操作,因此最终的余额为0,不存在数据脏读问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值