17,082
社区成员
发帖
与我相关
我的任务
分享
免费表 a
部门 免费点 产品
01 500 01
01 300 02
0101 100 01
0102 50 02
注:此表中,如果某部门不存在,要用上级部门的记录,是递归向上查询的
部门表 bm
编号 上级部门
01 00
0101 01
0102 01
0103 01
库存表 kc
id 部门 产品ID 价格
0001 0101 01 5000
0002 0102 02 60
0003 0103 02 40
0004 0103 01 520
0005 0103 01 110
0006 01 01 120
0007 01 02 700
要求用一条SQL,查询出价格在免费点以上的库存产品
如:
id 部门 产品ID 价格
0001 0101 01 5000
0002 0102 02 60
0004 0103 01 520
0007 01 02 700
在一个sql中完成太复杂了;添加一个函数,简化代码,当自己没有免费点的时候用来取父部门的免费点。
DROP TABLE a;
DROP TABLE bm;
DROP TABLE kc;
CREATE TABLE a (depid VARCHAR2(10),free INT,product VARCHAR2(10));
--部门 免费点 产品;
INSERT INTO A VALUES ('01', 500, '01');
INSERT INTO A VALUES ('01', 300, '02');
INSERT INTO A VALUES ('0101', 100, '01');
INSERT INTO A VALUES ('0102', 50, '02');
--注:此表中,如果某部门不存在,要用上级部门的记录,是递归向上查询的;
--部门表 bm;
CREATE TABLE bm(deptid VARCHAR2(10),parent_id VARCHAR2(10));
--编号 上级部门;
INSERT INTO BM VALUES ('01', '00');
INSERT INTO BM VALUES ('0101', '01');
INSERT INTO BM VALUES ('0102', '01');
INSERT INTO BM VALUES ('0103', '01');
--库存表 kc ;
CREATE TABLE kc(ID VARCHAR2(10),deptid VARCHAR2(10),product VARCHAR2(10),price INT);
--id 部门 产品ID 价格;
INSERT INTO KC VALUES ('0001', '0101', '01', 5000);
INSERT INTO KC VALUES ('0002', '0102', '02', 60);
INSERT INTO KC VALUES ('0003', '0103', '02', 40);
INSERT INTO KC VALUES ('0004', '0103', '01', 520);
INSERT INTO KC VALUES ('0005', '0103', '01', 110);
INSERT INTO KC VALUES ('0006', '01', '01', 120);
INSERT INTO KC VALUES ('0007', '01', '02', 700);
COMMIT;
CREATE OR REPLACE FUNCTION GET_FREE(P_DEPTID VARCHAR2, P_PRODUCT VARCHAR2)
RETURN INTEGER IS
V_RETURN INTEGER;
BEGIN
WITH M AS(
SELECT X.LL, A.PRODUCT, A.DEPID, A.FREE
FROM A,
(SELECT BM.*, LEVEL LL
FROM BM
START WITH DEPTID = P_DEPTID
CONNECT BY PRIOR PARENT_ID = DEPTID) X
WHERE A.DEPID = X.DEPTID
AND A.PRODUCT = P_PRODUCT)
SELECT FREE
INTO V_RETURN
FROM M
WHERE LL = (SELECT MIN(LL) FROM M);
RETURN(V_RETURN);
END GET_FREE;
/
SELECT KC.*
FROM KC,
(SELECT BM.PARENT_ID, BM.DEPTID, A.FREE, A.PRODUCT
FROM A, BM
WHERE A.DEPID(+) = BM.DEPTID) A
WHERE KC.PRICE > DECODE(FREE, NULL, GET_FREE(KC.DEPTID, KC.PRODUCT), FREE)
AND KC.DEPTID = A.DEPTID
AND KC.PRODUCT = DECODE(A.PRODUCT, NULL, KC.PRODUCT, A.PRODUCT)
/* AND kc.deptid='0103'
AND kc.product='01'*/
;
输出:
1 0001 0101 01 5000
2 0002 0102 02 60
3 0004 0103 01 520
4 0007 01 02 700
with a as (select '01' dept,540 free,'01' product from dual
union
select '01' dept,300 free,'02' product from dual
union
select '0101' dept,100 free,'01' product from dual
union
select '0102' dept,50 free,'02' product from dual
union
select '0103' dept,566 free,'02' product from dual
),
b as (select '01' dept,'00' priordept from dual
union
select '0101' dept,'01' from dual
union
select '0102' dept,'01' from dual
union
select '0103' dept,'01' from dual
union
select '010301' dept,'0103' from dual
),
c as (select '0001' id,'0101' dept,'01' productid,5000 price from dual
union
select '0002' id,'0102' dept,'02' productid,60 price from dual
union
select '0003' id,'0103' dept,'02' productid,40 price from dual
union
select '0004' id,'010301' dept,'01' productid,6000 price from dual
union
select '0005' id,'0103' dept,'01' productid,110 price from dual
union
select '0006' id,'01' dept,'01' productid,120 price from dual
union
select '0007' id,'01' dept,'02' productid,700 price from dual
)
select *
from c
where price > (select a.free
from a
where a.product = c.productid
and c.dept = a.dept)
union
select c.id, c.dept, c.productid, c.price
from (select c.*
from c
where c.dept not in (select a.dept from a)
and c.dept in (select b.dept from b)
) c,
b,
a
where c.dept = b.dept
and a.dept = b.priordept
and c.productid = a.product
and c.price > a.free
如果部门是三层以上,你这查询也不行啊,如上:
select '0004' id,'010301' dept,'01' productid,6000 price from dual
这行是应该出来的
但用这SQL,出不来啊
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.4.0
Connected as bm
SQL> c.productid
SQL> with a as (select '01' dept,500 free,'01' product from dual
2 union
3 select '01' dept,300 free,'02' product from dual
4 union
5 select '0101' dept,100 free,'01' product from dual
6 union
7 select '0102' dept,50 free,'02' product from dual
8 ),
9 b as (select '01' dept,'00' priordept from dual
10 union
11 select '0101' dept,'01' from dual
12 union
13 select '0102' dept,'01' from dual
14 union
15 select '0103' dept,'01' from dual
16 ),
17 c as (select '0001' id,'0101' dept,'01' productid,5000 price from dual
18 union
19 select '0002' id,'0102' dept,'02' productid,60 price from dual
20 union
21 select '0003' id,'0103' dept,'02' productid,40 price from dual
22 union
23 select '0004' id,'0103' dept,'01' productid,520 price from dual
24 union
25 select '0005' id,'0103' dept,'01' productid,110 price from dual
26 union
27 select '0006' id,'01' dept,'01' productid,120 price from dual
28 union
29 select '0007' id,'01' dept,'02' productid,700 price from dual
30 )
31 select *
32 from c
33 where price > (select a.free
34 from a
35 where a.product = c.productid
36 and c.dept = a.dept)
37 union
38 select c.id, c.dept, c.productid, c.price
39 from (select c.*
40 from c
41 where c.dept not in (select a.dept from a)
42 and c.dept in (select b.dept from b)) c,
43 b,
44 a
45 where c.dept = b.dept
46 and a.dept = b.priordept
47 and c.productid = a.product
48 and c.price > a.free
SQL> /
ID DEPT PRODUCTID PRICE
---- ---- --------- ----------
0001 0101 01 5000
0002 0102 02 60
0004 0103 01 520
0007 01 02 700
SQL>