逻辑上来说,where 子句的执行位于 group by 之前,where 子句执行时数据行还没有被分组,还不能使用 count 等函数
Oracle数据库的定制功能十分强大。Oracle不但允许用户定制自己的函数,还可以定制自己的聚集函数和分析函数。 本文将着重介绍使用自定义聚集函数建立一个字符串“sum”的示例: SQL> CREATE OR REPLACE TYPE T_LINK AS OBJECT ( 2 STR VARCHAR2(30000), 3 STATIC FUNCTION ODCIAGGREGATEINITIALIZE (SCTX IN OUT T_LINK) RETURN NUMBER, 4 MEMBER FUNCTION ODCIAGGREGATEITERATE (SELF IN OUT T_LINK, VALUE IN VARCHAR2) RETURN NUMBER, 5 MEMBER FUNCTION ODCIAGGREGATETERMINATE (SELF IN T_LINK, RETURNVALUE OUT VARCHAR2, FLAGS IN NUMBE R) RETURN NUMBER, 6 MEMBER FUNCTION ODCIAGGREGATEMERGE (SELF IN OUT T_LINK, CTX2 IN T_LINK) RETURN NUMBER 7 ) 8 / 类型已创建。 SQL> CREATE OR REPLACE TYPE BODY T_LINK IS 2 STATIC FUNCTION ODCIAGGREGATEINITIALIZE (SCTX IN OUT T_LINK) RETURN NUMBER IS 3 BEGIN 4 SCTX := T_LINK(NULL); 5 RETURN ODCICONST.SUCCESS; 6 END; 7 8 MEMBER FUNCTION ODCIAGGREGATEITERATE (SELF IN OUT T_LINK, VALUE IN VARCHAR2) RETURN NUMBER IS 9 BEGIN 10 SELF.STR := SELF.STR || VALUE; 11 RETURN ODCICONST.SUCCESS; 12 END; 13 14 MEMBER FUNCTION ODCIAGGREGATETERMINATE (SELF IN T_LINK, RETURNVALUE OUT VARCHAR2, FLAGS IN NUMBE R) RETURN NUMBER IS 15 BEGIN 16 RETURNVALUE := SELF.STR; 17 RETURN ODCICONST.SUCCESS; 18 END; 19 20 MEMBER FUNCTION ODCIAGGREGATEMERGE (SELF IN OUT T_LINK, CTX2 IN T_LINK) RETURN NUMBER IS 21 BEGIN 22 NULL; 23 RETURN ODCICONST.SUCCESS; 24 END; 25 END; 26 / 类型主体已创建。 SQL> CREATE OR REPLACE FUNCTION F_LINK (P_STR VARCHAR2) RETURN VARCHAR2 2 AGGREGATE USING T_LINK; 3 / 函数已创建。 SQL> CREATE TABLE TEST (ID NUMBER, NAME VARCHAR2(20)); 表已创建。 SQL> INSERT INTO TEST VALUES (1, 'AAA'); 已创建 1 行。 SQL> INSERT INTO TEST VALUES (2, 'BBB'); 已创建 1 行。 SQL> INSERT INTO TEST VALUES (1, 'ABC'); 已创建 1 行。 SQL> INSERT INTO TEST VALUES (3, 'CCC'); 已创建 1 行。 SQL> INSERT INTO TEST VALUES (2, 'DDD'); 已创建 1 行。 SQL> COMMIT; 提交完成。 SQL> COL NAME FORMAT A60 SQL> SELECT ID, F_LINK(NAME) NAME FROM TEST GROUP BY ID; ID NAME ---------- ------------------------------------------------------ 1 AAAABC 2 BBBDDD 3 CCC
上楼的谢谢,我还没学几天 ORACLE,只能看懂 CREATE OR REPLACE TYPE T_LINK 这句话和下面好部分。能不能再给我文字描述一下呀!
Oracle数据库的定制功能十分强大。Oracle不但允许用户定制自己的函数,还可以定制自己的聚集函数和分析函数。
本文将着重介绍使用自定义聚集函数建立一个字符串“sum”的示例: SQL> CREATE OR REPLACE TYPE T_LINK AS OBJECT (
2 STR VARCHAR2(30000),
3 STATIC FUNCTION ODCIAGGREGATEINITIALIZE
(SCTX IN OUT T_LINK) RETURN NUMBER,
4 MEMBER FUNCTION ODCIAGGREGATEITERATE
(SELF IN OUT T_LINK, VALUE IN VARCHAR2) RETURN NUMBER,
5 MEMBER FUNCTION ODCIAGGREGATETERMINATE
(SELF IN T_LINK, RETURNVALUE OUT VARCHAR2, FLAGS IN NUMBE
R) RETURN NUMBER,
6 MEMBER FUNCTION ODCIAGGREGATEMERGE
(SELF IN OUT T_LINK, CTX2 IN T_LINK) RETURN NUMBER
7 )
8 /
类型已创建。
SQL> CREATE OR REPLACE TYPE BODY T_LINK IS
2 STATIC FUNCTION ODCIAGGREGATEINITIALIZE
(SCTX IN OUT T_LINK) RETURN NUMBER IS
3 BEGIN
4 SCTX := T_LINK(NULL);
5 RETURN ODCICONST.SUCCESS;
6 END;
7
8 MEMBER FUNCTION ODCIAGGREGATEITERATE
(SELF IN OUT T_LINK, VALUE IN VARCHAR2) RETURN NUMBER IS
9 BEGIN
10 SELF.STR := SELF.STR || VALUE;
11 RETURN ODCICONST.SUCCESS;
12 END;
13
14 MEMBER FUNCTION ODCIAGGREGATETERMINATE
(SELF IN T_LINK, RETURNVALUE OUT VARCHAR2, FLAGS IN NUMBE
R) RETURN NUMBER IS
15 BEGIN
16 RETURNVALUE := SELF.STR;
17 RETURN ODCICONST.SUCCESS;
18 END;
19
20 MEMBER FUNCTION ODCIAGGREGATEMERGE
(SELF IN OUT T_LINK, CTX2 IN T_LINK) RETURN NUMBER IS
21 BEGIN
22 NULL;
23 RETURN ODCICONST.SUCCESS;
24 END;
25 END;
26 /
类型主体已创建。
SQL> CREATE OR REPLACE FUNCTION F_LINK
(P_STR VARCHAR2) RETURN VARCHAR2
2 AGGREGATE USING T_LINK;
3 /
函数已创建。
SQL> CREATE TABLE TEST (ID NUMBER, NAME VARCHAR2(20));
表已创建。
SQL> INSERT INTO TEST VALUES (1, 'AAA');
已创建 1 行。
SQL> INSERT INTO TEST VALUES (2, 'BBB');
已创建 1 行。
SQL> INSERT INTO TEST VALUES (1, 'ABC');
已创建 1 行。
SQL> INSERT INTO TEST VALUES (3, 'CCC');
已创建 1 行。
SQL> INSERT INTO TEST VALUES (2, 'DDD');
已创建 1 行。
SQL> COMMIT;
提交完成。
SQL> COL NAME FORMAT A60
SQL> SELECT ID, F_LINK(NAME) NAME FROM TEST GROUP BY ID;
ID NAME
---------- ------------------------------------------------------
1 AAAABC
2 BBBDDD
3 CCC
而聚合函数一般是对查询结果的计算
当执行完where的时候,啥结果都没有啊
SQL>
SQL> -- create demo table
SQL> create table Employee(
2 empno Number(3) NOT NULL, -- Employee ID
3 ename VARCHAR2(10 BYTE), -- Employee Name
4 hireDate DATE, -- Date Employee Hired
5 orig_salary Number(8,2), -- Orignal Salary
6 curr_salary Number(8,2), -- Current Salary
7 region VARCHAR2(1 BYTE) -- Region where employeed
8 )
9 /Table created.SQL>
SQL> create table job(
2 empno Number(3) NOT NULL, -- Employee ID
3 jobtitle VARCHAR2(10 BYTE) -- Employee job title
4 )
5 /Table created.SQL> -- prepare data for employee table
SQL> insert into Employee(empno, ename, hireDate, orig_salary, curr_salary, region)
2 values(122,'Alison',to_date('19960321','YYYYMMDD'), 45000, 48000, 'E')
3 /1 row created.SQL> insert into Employee(empno, ename, hireDate, orig_salary, curr_salary, region)
2 values(123, 'James',to_date('19781212','YYYYMMDD'), 23000, 32000, 'W')
3 /1 row created.SQL> insert into Employee(empno, ename, hireDate, orig_salary, curr_salary, region)
2 values(104,'Celia',to_date('19821024','YYYYMMDD'), 53000, 58000, 'E')
3 /1 row created.SQL> insert into Employee(empno, ename, hireDate, orig_salary, curr_salary, region)
2 values(105,'Robert',to_date('19840115','YYYYMMDD'), 31000, 36000, 'W')
3 /1 row created.SQL> insert into Employee(empno, ename, hireDate, orig_salary, curr_salary, region)
2 values(116,'Linda', to_date('19870730','YYYYMMDD'), 43000, 53000, 'E')
3 /1 row created.SQL> insert into Employee(empno, ename, hireDate, orig_salary, curr_salary, region)
2 values(117,'David', to_date('19901231','YYYYMMDD'), 78000, 85000, 'W')
3 /1 row created.SQL> insert into Employee(empno, ename, hireDate, orig_salary, curr_salary, region)
2 values(108,'Jode', to_date('19960917','YYYYMMDD'), 21000, 29000, 'E')
3 /1 row created.SQL>
SQL> -- prepare data for job table
SQL>
SQL> insert into job(empno, jobtitle)
2 values(101, 'Painter');1 row created.SQL>
SQL> insert into job(empno, jobtitle)
2 values(122, 'Tester');1 row created.SQL>
SQL> insert into job(empno, jobtitle)
2 values(123, 'Dediator');1 row created.SQL>
SQL> insert into job(empno, jobtitle)
2 values(104, 'Chemist');1 row created.SQL>
SQL> insert into job(empno, jobtitle)
2 values(105, 'Accountant');1 row created.SQL>
SQL> insert into job(empno, jobtitle)
2 values(116, 'Manager');1 row created.SQL>
SQL> insert into job(empno, jobtitle)
2 values(117, 'Programmer');1 row created.SQL>
SQL> insert into job(empno, jobtitle)
2 values(108, 'Developer');1 row created.SQL>
SQL>
SQL> -- display data in the table
SQL> select * from Employee
2 /
Hit a key to continue EMPNO ENAME HIREDATE ORIG_SALARY CURR_SALARY R
---------- ---------- --------- ----------- ----------- -
122 Alison 21-MAR-96 45000 48000 E
123 James 12-DEC-78 23000 32000 W
104 Celia 24-OCT-82 53000 58000 E
105 Robert 15-JAN-84 31000 36000 W
116 Linda 30-JUL-87 43000 53000 E
117 David 31-DEC-90 78000 85000 W
108 Jode 17-SEP-96 21000 29000 E7 rows selected.SQL> select * from job;
Hit a key to continue EMPNO JOBTITLE
---------- ----------
101 Painter
122 Tester
123 Dediator
104 Chemist
105 Accountant
116 Manager
117 Programmer
108 Developer8 rows selected.SQL>
SQL>
SQL> -- Using HAVING with an Analytical Function
SQL>
SQL> -- if a HAVING clause is added, it will have its effect just before the RANK.
SQL>
SQL> SELECT j.jobtitle, COUNT(*), MAX(orig_salary) maxsalary,
2 MIN(orig_salary) minsalary
3 -- RANK() OVER(ORDER BY MAX(orig_salary)) rankorder
4 FROM employee e, job j
5 WHERE e.orig_salary < 43000
6 AND e.empno = j.empno
7 GROUP BY j.jobtitle
8 HAVING MAX(orig_salary) > 34000
9 ORDER BY j.jobtitle desc;no rows selectedSQL>
SQL>
SQL>
SQL>
SQL>
SQL>
SQL> drop table job;Table dropped.SQL>
SQL> -- clean the table
SQL> drop table Employee;Table dropped.