PL SQL 包含多个表的函数
PL SQL function that includes multiple tables
我是 PL SQL 的新手,必须编写一个函数,该函数以 customer_id
作为输入,并且必须为此输出 product_name
的最畅销产品customer_id
.
架构如下所示:
我找到了很多包含两个表的简单示例,但我似乎找不到一个必须进行多个连接并使用一个函数,同时只选择最畅销产品的示例。
我可以在这里粘贴很多非常糟糕的代码以及我是如何尝试解决这个问题的,但是对于我目前的知识来说这似乎有点难以理解,因为我一直在学习 PL SQL不到3天就接到了这个任务
使用一些示例数据(最小列集):
SQL> select * from products order by product_id;
PRODUCT_ID PRODUCT_NAME
---------- ----------------
1 BMW
2 Audi
SQL> select * From order_items;
PRODUCT_ID CUSTOM QUANTITY UNIT_PRICE
---------- ------ ---------- ----------
1 Little 100 1
1 Little 200 2
2 Foot 300 3
如果我们检查一些总数:
SQL> select o.product_id,
2 o.customer_id,
3 sum(o.quantity * o.unit_price) total
4 from order_items o
5 group by o.product_id, o.customer_id;
PRODUCT_ID CUSTOM TOTAL
---------- ------ ----------
2 Little 400
1 Little 100
2 Foot 900
SQL>
上面写着
- 对于客户 Little,产品 2 的总销量 = 400 - 这是我们对 Little 的选择
- 对于客户 Little,产品 1 已售出,总计 = 100
- 对于客户 Foot,产品 2 的总销量 = 900 - 这是我们对 Foot 的选择
查询可能如下所示:
temp
CTE 计算每个客户的总数
rank_them
CTE 对每个客户按降序排列; row_number
这样即使有平局,您也只能得到一种产品
- 最后,select排名最高的那个
SQL> with
2 temp as
3 (select o.product_id,
4 o.customer_id,
5 sum(o.quantity * o.unit_price) total
6 from order_items o
7 group by o.product_id, o.customer_id
8 ),
9 rank_them as
10 (select t.customer_id,
11 t.product_id,
12 row_number() over (partition by t.customer_id order by t.total desc) rn
13 from temp t
14 )
15 select * From rank_them;
CUSTOM PRODUCT_ID RN
------ ---------- ----------
Foot 2 1 --> for Foot, product 2 ranks as the highest
Little 2 1 --> for Little, product 1 ranks as the highest
Little 1 2
SQL>
移动到函数:
SQL> create or replace function f_product (par_customer_id in order_items.customer_id%type)
2 return products.product_name%type
3 is
4 retval products.product_name%type;
5 begin
6 with
7 temp as
8 (select o.product_id,
9 o.customer_id,
10 sum(o.quantity * o.unit_price) total
11 from order_items o
12 group by o.product_id, o.customer_id
13 ),
14 rank_them as
15 (select t.customer_id,
16 t.product_id,
17 row_number() over (partition by t.customer_id order by t.total desc) rn
18 from temp t
19 )
20 select p.product_name
21 into retval
22 from rank_them r join products p on p.product_id = r.product_id
23 where r.customer_id = par_customer_id
24 and r.rn = 1;
25
26 return retval;
27 end;
28 /
Function created.
SQL>
测试:
SQL> select f_product ('Little') result from dual;
RESULT
--------------------------------------------------------------------------------
Audi
SQL> select f_product ('Foot') result from dual;
RESULT
--------------------------------------------------------------------------------
Audi
SQL>
现在,您可以对其进行改进,以便您关心 未找到数据 问题(当客户没有购买任何东西时),领带(但您随后 return 一个集合或一个 refcursor 而不是一个标量值)等
[编辑] 对不起,ORDERS
table 必须包含在临时 CTE
中;您的数据模型是正确的,您无需为此做任何事情 - 我的查询是错误的(小屏幕 + 迟到问题;不是真正的借口,只是说)。
所以:
with
temp as
(select i.product_id,
o.customer_id,
sum(i.quantity * i.unit_price) total
from order_items i join orders o on o.order_id = i.order_id
group by i.product_id, o.customer_id
),
我的其余代码 - 否则 - 未修改。
我是 PL SQL 的新手,必须编写一个函数,该函数以 customer_id
作为输入,并且必须为此输出 product_name
的最畅销产品customer_id
.
架构如下所示:
我找到了很多包含两个表的简单示例,但我似乎找不到一个必须进行多个连接并使用一个函数,同时只选择最畅销产品的示例。
我可以在这里粘贴很多非常糟糕的代码以及我是如何尝试解决这个问题的,但是对于我目前的知识来说这似乎有点难以理解,因为我一直在学习 PL SQL不到3天就接到了这个任务
使用一些示例数据(最小列集):
SQL> select * from products order by product_id;
PRODUCT_ID PRODUCT_NAME
---------- ----------------
1 BMW
2 Audi
SQL> select * From order_items;
PRODUCT_ID CUSTOM QUANTITY UNIT_PRICE
---------- ------ ---------- ----------
1 Little 100 1
1 Little 200 2
2 Foot 300 3
如果我们检查一些总数:
SQL> select o.product_id,
2 o.customer_id,
3 sum(o.quantity * o.unit_price) total
4 from order_items o
5 group by o.product_id, o.customer_id;
PRODUCT_ID CUSTOM TOTAL
---------- ------ ----------
2 Little 400
1 Little 100
2 Foot 900
SQL>
上面写着
- 对于客户 Little,产品 2 的总销量 = 400 - 这是我们对 Little 的选择
- 对于客户 Little,产品 1 已售出,总计 = 100
- 对于客户 Foot,产品 2 的总销量 = 900 - 这是我们对 Foot 的选择
查询可能如下所示:
temp
CTE 计算每个客户的总数rank_them
CTE 对每个客户按降序排列;row_number
这样即使有平局,您也只能得到一种产品- 最后,select排名最高的那个
SQL> with
2 temp as
3 (select o.product_id,
4 o.customer_id,
5 sum(o.quantity * o.unit_price) total
6 from order_items o
7 group by o.product_id, o.customer_id
8 ),
9 rank_them as
10 (select t.customer_id,
11 t.product_id,
12 row_number() over (partition by t.customer_id order by t.total desc) rn
13 from temp t
14 )
15 select * From rank_them;
CUSTOM PRODUCT_ID RN
------ ---------- ----------
Foot 2 1 --> for Foot, product 2 ranks as the highest
Little 2 1 --> for Little, product 1 ranks as the highest
Little 1 2
SQL>
移动到函数:
SQL> create or replace function f_product (par_customer_id in order_items.customer_id%type)
2 return products.product_name%type
3 is
4 retval products.product_name%type;
5 begin
6 with
7 temp as
8 (select o.product_id,
9 o.customer_id,
10 sum(o.quantity * o.unit_price) total
11 from order_items o
12 group by o.product_id, o.customer_id
13 ),
14 rank_them as
15 (select t.customer_id,
16 t.product_id,
17 row_number() over (partition by t.customer_id order by t.total desc) rn
18 from temp t
19 )
20 select p.product_name
21 into retval
22 from rank_them r join products p on p.product_id = r.product_id
23 where r.customer_id = par_customer_id
24 and r.rn = 1;
25
26 return retval;
27 end;
28 /
Function created.
SQL>
测试:
SQL> select f_product ('Little') result from dual;
RESULT
--------------------------------------------------------------------------------
Audi
SQL> select f_product ('Foot') result from dual;
RESULT
--------------------------------------------------------------------------------
Audi
SQL>
现在,您可以对其进行改进,以便您关心 未找到数据 问题(当客户没有购买任何东西时),领带(但您随后 return 一个集合或一个 refcursor 而不是一个标量值)等
[编辑] 对不起,ORDERS
table 必须包含在临时 CTE
中;您的数据模型是正确的,您无需为此做任何事情 - 我的查询是错误的(小屏幕 + 迟到问题;不是真正的借口,只是说)。
所以:
with
temp as
(select i.product_id,
o.customer_id,
sum(i.quantity * i.unit_price) total
from order_items i join orders o on o.order_id = i.order_id
group by i.product_id, o.customer_id
),
我的其余代码 - 否则 - 未修改。