如何将 table 的水平值绑定到 oracle 数据库中另一个 table 的垂直值
How to bind horizontal values of a table to a vertical values of another table in oracle database
我有 2 个 table。
以属性开头的列是根据部门更改的。属性的描述在这里
我的要求是获取每个属性的值及其基于部门的主键,如下所示 table。
老实说,我在我的程序中遇到了这个问题。我没有更改 tables 的权限,也没有通用的唯一密钥 column.i 如果有人可以向我提供建议,我将不胜感激。
WITH clause 是 Oracle 9.2 添加的,应该可以解决问题。对于其他属性,只需添加更多子查询,其中过滤器为 att.attribute = 'attribute2' 或 'Attribute3'...
WITH e AS
(SELECT emp.employee_ID, emp.department, emp.attribute1
FROM employee emp),
a AS (SELECT att.attribute_id, att.attribute, att.meaning
FROM attribute_TYPE att
WHERE att.attribute = 'attribute1')a
SELECT e.employeeid, att.attributeid, e.department, a.attribute,
a.meaning e.attribute1
FROM e JOIN a ON e.department = a.department
with a as (
select a.*, row_number() over (partition by department order by attributeID) rn
from attributes a),
e as (
select employeeId, department, attribute1, 1 rn from employees union all
select employeeId, department, attribute2, 2 rn from employees union all
select employeeId, department, attribute3, 3 rn from employees
)
select e.employeeId, a.attributeid, e.department, a.attribute, a.meaning,
e.attribute1 as value
from e join a on a.department=e.department and a.rn=e.rn
order by e.employeeId, a.attributeid
测试数据及输出:
create table employees (employeeID number(3), name varchar2(10), department varchar2(5), age number(3), attribute1 varchar2(10), attribute2 varchar2(10), attribute3 varchar2(10));
insert into employees values (1, 'john', 'IT', 22, 'attr1val1', 'attr2val2', null);
insert into employees values (2, 'jane', 'HR', 32, 'attr1val3', 'attr2val4', 'attr3val5');
insert into employees values (3, 'joe', 'HR', 23, 'attr1val6', 'attr2val7', 'attr3val8');
insert into employees values (4, 'jack', 'IT', 45, 'attr1val9', 'attr2val10', null);
create table attributes (attributeID number(3), department varchar2(10), attribute varchar2(10), meaning varchar2(10));
insert into attributes values (1, 'IT', 'attribute1', 'laptoptype');
insert into attributes values (2, 'IT', 'attribute2', 'networkloc');
insert into attributes values (3, 'HR', 'attribute1', 'location');
insert into attributes values (4, 'HR', 'attribute2', 'position');
insert into attributes values (5, 'HR', 'attribute3', 'allocation');
EMPLOYEEID ATTRIBUTEID DEPARTMENT ATTRIBUTE MEANING VALUE
---------- ----------- ---------- ---------- ---------- ----------
1 1 IT attribute1 laptoptype attr1val1
1 2 IT attribute2 networkloc attr2val2
2 3 HR attribute1 location attr1val3
2 4 HR attribute2 position attr2val4
2 5 HR attribute3 allocation attr3val5
3 3 HR attribute1 location attr1val6
3 4 HR attribute2 position attr2val7
3 5 HR attribute3 allocation attr3val8
4 1 IT attribute1 laptoptype attr1val9
4 2 IT attribute2 networkloc attr2val10
编辑:解释
在回答中我使用了 with
子句只是将解决方案划分为可读的步骤。如果是,您可以将它们移动到主查询的 from
子句中
更舒适 table 给你。无论如何:子查询 a
从 table attributes
读取数据并添加行数,
所以对于每个部门,它们总是从 1 开始编号。我为此使用了 row_number()。子查询e
联合(全部)需要的属性和数字
他们相应地。然后在两个子查询中生成的数字用于主连接:a.department=e.department and a.rn=e.rn
.
备选方案 1 - 如果您使用的是 Oracle 11g,则可以使用 unpivot。查看子查询生成的内容,以及如何与 attributes
table:
连接
with e as (
select employeeId, name, department, attribute, value from employees
unpivot (value for attribute in ("ATTRIBUTE1", "ATTRIBUTE2", "ATTRIBUTE3"))
)
select e.employeeId, a.attributeid, e.department, a.attribute,
a.meaning, e.value
from e join attributes a on a.department=e.department
and lower(a.attribute)=lower(e.attribute)
order by e.employeeId, a.attributeid;
替代方案 2 - 带有分层子查询生成器(子查询 r
),由 connect by
实现,它简单地从 1、2、3 创建数字,它们是接下来加入 employees
和适当的属性
作为值附加在 case
子句中。休息方式与原始答案类似。
with a as (
select a.*, row_number() over (partition by department order by attributeID) rn
from attributes a),
r as (select level rn from dual connect by level<=3),
e as (
select employeeId, department, rn,
case when r.rn = 1 then attribute1
when r.rn = 2 then attribute2
when r.rn = 3 then attribute3
end value
from employees cross join r
)
select e.employeeId, a.attributeid, e.department, a.attribute,
a.meaning, e.value
from e join a on a.department=e.department and a.rn=e.rn
order by e.employeeId, a.attributeid
所有三个版本都给了我相同的输出。我还在具有 100k 行的类似 table 上测试了第一个选项,并在几秒钟内获得输出(对于 5 个属性)。请测试所有解决方案并尝试理解它们。如果您可以使用 unpivot 版本,我会更喜欢这个。
抱歉延迟解释和任何语言错误。
我有 2 个 table。
以属性开头的列是根据部门更改的。属性的描述在这里
我的要求是获取每个属性的值及其基于部门的主键,如下所示 table。
老实说,我在我的程序中遇到了这个问题。我没有更改 tables 的权限,也没有通用的唯一密钥 column.i 如果有人可以向我提供建议,我将不胜感激。
WITH clause 是 Oracle 9.2 添加的,应该可以解决问题。对于其他属性,只需添加更多子查询,其中过滤器为 att.attribute = 'attribute2' 或 'Attribute3'...
WITH e AS
(SELECT emp.employee_ID, emp.department, emp.attribute1
FROM employee emp),
a AS (SELECT att.attribute_id, att.attribute, att.meaning
FROM attribute_TYPE att
WHERE att.attribute = 'attribute1')a
SELECT e.employeeid, att.attributeid, e.department, a.attribute,
a.meaning e.attribute1
FROM e JOIN a ON e.department = a.department
with a as (
select a.*, row_number() over (partition by department order by attributeID) rn
from attributes a),
e as (
select employeeId, department, attribute1, 1 rn from employees union all
select employeeId, department, attribute2, 2 rn from employees union all
select employeeId, department, attribute3, 3 rn from employees
)
select e.employeeId, a.attributeid, e.department, a.attribute, a.meaning,
e.attribute1 as value
from e join a on a.department=e.department and a.rn=e.rn
order by e.employeeId, a.attributeid
测试数据及输出:
create table employees (employeeID number(3), name varchar2(10), department varchar2(5), age number(3), attribute1 varchar2(10), attribute2 varchar2(10), attribute3 varchar2(10));
insert into employees values (1, 'john', 'IT', 22, 'attr1val1', 'attr2val2', null);
insert into employees values (2, 'jane', 'HR', 32, 'attr1val3', 'attr2val4', 'attr3val5');
insert into employees values (3, 'joe', 'HR', 23, 'attr1val6', 'attr2val7', 'attr3val8');
insert into employees values (4, 'jack', 'IT', 45, 'attr1val9', 'attr2val10', null);
create table attributes (attributeID number(3), department varchar2(10), attribute varchar2(10), meaning varchar2(10));
insert into attributes values (1, 'IT', 'attribute1', 'laptoptype');
insert into attributes values (2, 'IT', 'attribute2', 'networkloc');
insert into attributes values (3, 'HR', 'attribute1', 'location');
insert into attributes values (4, 'HR', 'attribute2', 'position');
insert into attributes values (5, 'HR', 'attribute3', 'allocation');
EMPLOYEEID ATTRIBUTEID DEPARTMENT ATTRIBUTE MEANING VALUE
---------- ----------- ---------- ---------- ---------- ----------
1 1 IT attribute1 laptoptype attr1val1
1 2 IT attribute2 networkloc attr2val2
2 3 HR attribute1 location attr1val3
2 4 HR attribute2 position attr2val4
2 5 HR attribute3 allocation attr3val5
3 3 HR attribute1 location attr1val6
3 4 HR attribute2 position attr2val7
3 5 HR attribute3 allocation attr3val8
4 1 IT attribute1 laptoptype attr1val9
4 2 IT attribute2 networkloc attr2val10
编辑:解释
在回答中我使用了 with
子句只是将解决方案划分为可读的步骤。如果是,您可以将它们移动到主查询的 from
子句中
更舒适 table 给你。无论如何:子查询 a
从 table attributes
读取数据并添加行数,
所以对于每个部门,它们总是从 1 开始编号。我为此使用了 row_number()。子查询e
联合(全部)需要的属性和数字
他们相应地。然后在两个子查询中生成的数字用于主连接:a.department=e.department and a.rn=e.rn
.
备选方案 1 - 如果您使用的是 Oracle 11g,则可以使用 unpivot。查看子查询生成的内容,以及如何与 attributes
table:
with e as (
select employeeId, name, department, attribute, value from employees
unpivot (value for attribute in ("ATTRIBUTE1", "ATTRIBUTE2", "ATTRIBUTE3"))
)
select e.employeeId, a.attributeid, e.department, a.attribute,
a.meaning, e.value
from e join attributes a on a.department=e.department
and lower(a.attribute)=lower(e.attribute)
order by e.employeeId, a.attributeid;
替代方案 2 - 带有分层子查询生成器(子查询 r
),由 connect by
实现,它简单地从 1、2、3 创建数字,它们是接下来加入 employees
和适当的属性
作为值附加在 case
子句中。休息方式与原始答案类似。
with a as (
select a.*, row_number() over (partition by department order by attributeID) rn
from attributes a),
r as (select level rn from dual connect by level<=3),
e as (
select employeeId, department, rn,
case when r.rn = 1 then attribute1
when r.rn = 2 then attribute2
when r.rn = 3 then attribute3
end value
from employees cross join r
)
select e.employeeId, a.attributeid, e.department, a.attribute,
a.meaning, e.value
from e join a on a.department=e.department and a.rn=e.rn
order by e.employeeId, a.attributeid
所有三个版本都给了我相同的输出。我还在具有 100k 行的类似 table 上测试了第一个选项,并在几秒钟内获得输出(对于 5 个属性)。请测试所有解决方案并尝试理解它们。如果您可以使用 unpivot 版本,我会更喜欢这个。 抱歉延迟解释和任何语言错误。