我想为成员(member)提供该类(class)费用 20% 的折扣 谁在上个季度上过课(如果成员(member)上过 连续三个季度上课,最后两个季度她将获得折扣)。并总结我给出的所有折扣($)。
这是数据库中的表:
注册(class_id、member_id、费用)
CLASS(class_id、season、year)和属性season可以是Spring、Summer、Fall、Winter。
数据看起来像这样:
注册
Class_id Member_id Cost
-------- --------- ----
3 3 20
1 9 15
2 9 20
4 10 30
3 10 10
5 5 10
4 9 30
...
类
class_id Season Year
-------- ------ ----
1 Spring 2008
2 Fall 2008
3 Spring 2009
4 Winter 2008
5 Summer 2008
...
最佳答案
首先,您的数据模型让您很为难。您需要一种简单的方法来识别连续的季度,因此,您需要一个表来保存该信息,其中一个键是递增的增量:否则您如何期望计算机知道 2009 年 Spring 紧接着 2008 年冬季?
无论如何,这是我的测试数据版本。我使用名称是为了更容易看到发生了什么:
SQL> select s.name as student
2 , c.name as class
3 , q.season||' '||q.year as quarter
4 , q.q_id
5 , c.base_cost
6 from enrolments e
7 join students s
8 on (s.s_id = e.s_id)
9 join classes c
10 on (c.c_id = e.c_id)
11 join quarters q
12 on (q.q_id = c.q_id)
13 order by s.s_id, q.q_id
14 /
STUDENT CLASS QUARTER Q_ID BASE_COST
---------- -------------------- --------------- ---------- ----------
Sheldon Introduction to SQL Spring 2008 100 100
Sheldon Advanced SQL Spring 2009 104 150
Howard Introduction to SQL Spring 2008 100 100
Howard Information Theory Summer 2008 101 75
Rajesh Information Theory Summer 2008 101 75
Leonard Crypto Foundation Autumn 2008 102 120
Leonard PHP for Dummies Winter 2008 103 90
Leonard Advanced SQL Spring 2009 104 150
8 rows selected.
SQL>
如您所见,我有一个表 QUARTERS,其主键 Q_ID 按日历顺序递增。
我将使用 Oracle 语法来解决这个问题,特别是 LAG 分析函数:
SQL> select s.name as student
2 , c.name as class
3 , q.season||' '||q.year as quarter
4 , q.q_id
5 , c.base_cost
6 , lag (q.q_id) over (partition by s.s_id order by q.q_id) prev_q_id
7 from enrolments e
8 join students s
9 on (s.s_id = e.s_id)
10 join classes c
11 on (c.c_id = e.c_id)
12 join quarters q
13 on (q.q_id = c.q_id)
14 order by s.s_id, q.q_id
15 /
STUDENT CLASS QUARTER Q_ID BASE_COST PREV_Q_ID
---------- -------------------- --------------- ---------- ---------- ----------
Sheldon Introduction to SQL Spring 2008 100 100
Sheldon Advanced SQL Spring 2009 104 150 100
Howard Introduction to SQL Spring 2008 100 100
Howard Information Theory Summer 2008 101 75 100
Rajesh Information Theory Summer 2008 101 75
Leonard Crypto Foundation Autumn 2008 102 120
Leonard PHP for Dummies Winter 2008 103 90 102
Leonard Advanced SQL Spring 2009 104 150 103
8 rows selected.
SQL>
因此,通过查看 PREV_Q_ID 列,我们可以看到 Howard、Sheldon 和 Leonard 都上过不止一门类(class)。只有伦纳德上过三门课。通过比较 PREV_Q_ID 和 Q_ID 列中的值,我们可以看到 Howard 的两个类(class)在连续的宿舍中,而 Sheldon 的则不是。
现在我们可以做一些数学运算了:
SQL> select student
2 , class
3 , quarter
4 , base_cost
5 , discount*100 as discount_pct
6 , base_cost - (base_cost*discount) as actual_cost
7 from
8 ( select student
9 , class
10 , quarter
11 , base_cost
12 , case
13 when prev_q_id is not null
14 and q_id - prev_q_id = 1
15 then 0.2
16 else 0
17 end as discount
18 , s_id
19 , q_id
20 from
21 (
22 select s.name as student
23 , c.name as class
24 , q.season||' '||q.year as quarter
25 , q.q_id
26 , c.base_cost
27 , lag (q.q_id) over (partition by s.s_id order by q.q_id) prev_q_id
28 , s.s_id
29 from enrolments e
30 join students s
31 on (s.s_id = e.s_id)
32 join classes c
33 on (c.c_id = e.c_id)
34 join quarters q
35 on (q.q_id = c.q_id)
36 )
37 )
38 order by s_id, q_id
39 /
(人为中断以避免向下滚动以查看结果的需要)
STUDENT CLASS QUARTER BASE_COST DISCOUNT_PCT ACTUAL_COST
---------- -------------------- ----------- ---------- ------------ -----------
Sheldon Introduction to SQL Spring 2008 100 0 100
Sheldon Advanced SQL Spring 2009 150 0 150
Howard Introduction to SQL Spring 2008 100 0 100
Howard Information Theory Summer 2008 75 20 60
Rajesh Information Theory Summer 2008 75 0 75
Leonard Crypto Foundation Autumn 2008 120 0 120
Leonard PHP for Dummies Winter 2008 90 20 72
Leonard Advanced SQL Spring 2009 150 20 120
8 rows selected.
SQL>
因此,Howard 和 Leonard 的连续类(class)获得折扣,而 Sheldon 和 Raj 则没有。
关于mysql - SQL查找连续的季度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7116576/