3个表联合查询,怎么写SQL ?
超市抽奖活动查询
表a:(抽奖时间公布表)
字段:ID(序号) ,start_time(开始时间) ,end_time(结束时间) ,name(本次抽奖活动名称)
数据如:
001,2008-10-10 ,2008-10-15 ,饮料促销活动
002,2008-11-10 ,2008-11-15 ,蔬菜促销活动
003,2008-12-10 ,2008-12-15 ,粮油促销活动
表b: (客户在超市消费的积分表)
字段:user_id(客户ID) , user_name(客户名字) ,xf_time(消费时间),score(积分)
数据如:
000001,小李,2008-12-10,5
000001,小李,2008-12-11,3
000002,小一,2008-12-14,5
000002,小一,2008-12-13,3
000003,小二,2008-12-10,1
000003,小二,2008-12-14,3
000004,小三,2008-12-14,1
表c: (参加抽奖活动记录表)
字段:ID(序号) ,user_id(客户ID) ,use_name(客户名字) ,record(抽奖记录)
数据如:
002,000004, 小三,抽了第一注
002,000004, 小三,抽了第二注
002,000002, 小一,抽了第一注
表之间的关联:a.ID = b.ID
我想查询的结果是:
再距当前最近的抽奖活动日期范围里,有那些客户在超市消费了,而且消费积分超过3分的就可以抽5注,积分小于小分的只能抽3注,
并且能得到,当前用户是否已经参加抽奖了,如果已经参加了,那他还可以再抽几注?
SQL 怎么写呢?
[解决办法]
可抽注数:
select b.user_id, b.user_name,case when b.score>3 then 5 else 3 end 可抽注数
from
b,(select max(end_time) end_time from a)a
where b.xf_time=a.end_time
[解决办法]
select b.user_id, b.user_name,case when b.score>3 then 5 else 3 end 可抽注数,c.num 已抽注数
from b,(select max(end_time) end_time from a)a
on b.xf_time=a.end_time
left join (select user_id,user_name,count(*) num from c group by user_id,user_name)c
on b.user_id=c.user_id and b.user_name=c.user_name
[解决办法]
表之间的关联:a.ID = b.ID
b里面有id?
只要用子查询+关联就可以了
[解决办法]
select a.id ,(user_id,case when score>3 then 5 else 3 end as times ,recordfrom a,(select b.user_id,score,max(xf_time)as last_time ,record from b ,cwhere b.user_id = c.user_idgroup by b.user_id,score,record) fwhere a.end_time<f.last_time--楼主在加上详细的条件
[解决办法]
select a.id ,user_id,case when score>3 then 5 else 3 end as times ,recordfrom a,(select b.user_id,score,max(xf_time)as last_time ,record from b ,cwhere b.user_id = c.user_idgroup by b.user_id,score,record) fwhere a.end_time<f.last_time--楼主在加上详细的条件
[解决办法]
select b.user_id,
case
when max(b.score) > 3 then
5
else
3
end 可抽注数,
count(c.user_id) 已抽注数
from b,c
where b.user_id = c.user_id(+)
group by b.user_id
不知道楼主想查出ID字段的意义是什么,若说是最近的但是抽奖活动记录表中没得时间字段,仅给出部分代码以供参考
感觉表的设计结构有所累赘
[解决办法]
上面的语句还有点问题,更新如下:
select b.user_id,
case
when max(b.score) > 3 then
5
else
3
end 可抽注数,
case
when (select count(c.user_id)
from c
where user_id = b.user_id
group by user_id) is null then
0
else
(select count(c.user_id)
from c
where user_id = b.user_id
group by user_id)
end 已抽注数
from b, c
where b.user_id = c.user_id(+)
group by b.user_id
继续跟踪,发现有问题或更好的方法请指教
------解决方案--------------------
CREATE TABLE a (ID VARCHAR2(10),start_time DATE,end_time DATE,NAME VARCHAR2(20));INSERT INTO a VALUES('001',d('2008-10-10'),d('2008-10-15'),'饮料促销活动');INSERT INTO a VALUES('002',d('2008-11-10'),d('2008-11-15'),'蔬菜促销活动');INSERT INTO a VALUES('003',d('2008-12-10'),d('2008-12-15'),'粮油促销活动');CREATE TABLE b (user_id VARCHAR2(10),user_name VARCHAR2(10),xf_time DATE,score NUMBER(10));INSERT INTO b VALUES('000001','小李',d('2008-12-10'),5);INSERT INTO b VALUES('000001','小李',d('2008-12-11'),3);INSERT INTO b VALUES('000002','小一',d('2008-12-14'),5);INSERT INTO b VALUES('000002','小一',d('2008-12-13'),3);INSERT INTO b VALUES('000003','小二',d('2008-12-10'),1);INSERT INTO b VALUES('000003','小二',d('2008-12-14'),3);INSERT INTO b VALUES('000004','小三',d('2008-12-14'),1);CREATE TABLE c(ID VARCHAR2(10),user_id VARCHAR2(10),user_name VARCHAR2(10),RECORD VARCHAR2(10));INSERT INTO c VALUES('002','000004','小三','抽了第一注');INSERT INTO c VALUES('002','000004','小三','抽了第二注');INSERT INTO c VALUES('002','000002','小一','抽了第一注');INSERT INTO c VALUES('003','000002','小一','抽了第一注');--- 这里添加了一条 小一 对 003 的抽奖记录,为了就是测试记录,让结果有点变化SELECT m.user_id AS "用户代码",m.user_name AS "用户名", (CASE WHEN m.score > 3 THEN 5 ELSE 3 END) - nvl(n.cou,0) AS "可抽次数"FROM (SELECT user_id,user_name ,a.id ,SUM(score)score FROM b ,a WHERE a.id = (SELECT ID FROM a WHERE a.start_time = ( SELECT MAX(start_time) FROM a)) AND b.xf_time BETWEEN a.start_time AND a.end_time GROUP BY user_id,user_name ,a.id)m LEFT JOIN (SELECT ID ,USER_id ,COUNT(1)cou FROM c GROUP BY ID ,user_id) n ON m.user_id = n.user_id AND m.id = n.id用户代码 用户名 可抽次数000002 小一 4000003 小二 5000004 小三 3000001 小李 5
[解决办法]
先分析一下业务吧!
首先要求,是离当前日期最近的促销活动。正在进行的促销活动算不算最近的?还是只是统计已经结束的促销活动?
[解决办法]
借用12楼的表用用啊。
LZ是不是这个意思:暂且不考虑时间的因素。
一个人如果他的总消费积分超过3分,则有5次抽奖机会,少于3分则只有3次抽奖机会。一个人当前的可用抽奖次数,为总积分抽奖次数减去已经使用的抽奖次数,为最后可用的抽奖次数。
实现的过程中,我觉得用函数来统计已经使用的抽奖次数,这样比较容易。
create or replace function F_sum(args_user_id c.user_id%type)return numberas ret number :=0;begin select count(*) into ret from c where c.user_id=args_user_id;return ret;end;--统计已经抽奖的人的次数 select distinct user_id ,user_name --,xf_time -- ,score ,sum(score) over(partition by user_id) sum_jf ,case when sum(score) over(partition by user_id)>3 then 5 when sum(score) over(partition by user_id)<3 then 3 end - f_sum(user_id) ky ,f_sum(user_id)from b