给定下表
TYPE MYTYPE IS VARRAY(100) OF NUMBER;
CREATE TABLE EMPLOYEES(ID NUMBER(*), SALARY_HISTORY(MYTYPE) );
如何计算SALARY_HISTORY列中的元素数,以便在该列中列出员工的所有工资?
请参阅下面演示底部的查询。我使用了您的代码,但将表命名为E
,因为我已经有一个表EMPLOYEES
.请注意,SQL 不是 PL/SQL;若要在 SQL 中使用您的类型,必须使用CREATE TYPE
语句。
create TYPE MYTYPE IS VARRAY(100) OF NUMBER;
/
CREATE TABLE E(ID NUMBER, SALARY_HISTORY MYTYPE );
insert into e values (1, mytype(1, 2, 3));
insert into e values (3, mytype(33, 22, 0, 33, 0));
select * from e;
ID SALARY_HISTORY
-- ------------------------------
1 INTRO.MYTYPE(1, 2, 3)
3 INTRO.MYTYPE(33, 22, 0, 33, 0)
select id, count(*)
from e, table(e.salary_history)
group by id;
ID COUNT(*)
----- ----------
1 3
3 5
或者,也许(如果需要): -column_value
是table
运算符生成的列的名称。
select id, count(distinct column_value) as distinct_cnt
from e, table(e.salary_history)
group by id;
ID DISTINCT_CNT
----- ------------
1 3
3 3
如果可能,将数据模型转换为常规关系表。 大约一半的程序员知道如何使用SQL。 可能只有不到0.01%的人知道如何查询VARRAY。 如果没有人知道如何查询数据库,数据库的意义何在? 当您需要向历史记录信息添加日期列或遇到性能问题时,您将怎么做?
如果必须使用对象关系列,则嵌套表会使事情变得简单一些,并避免限制元素的数量。
create or replace type mytype is table of number;
create table employees(id number(*), salary_history mytype)
nested table salary_history store as employees_salary_history;
insert into employees values(null, null);
insert into employees values(0, mytype());
insert into employees values(1, mytype(1));
insert into employees values(2, mytype(1,2));
insert into employees values(3, mytype(1,2,3));
select id, nvl(cardinality(salary_history), 0) salary_count
from employees;
ID SALARY_COUNT
-- ------------
0
0 0
1 1
2 2
3 3
如果您坚持使用当前的数据模型,那么 Mathguy 的答案应该有效,尽管交叉联接可能会导致性能问题。