以属性开头的列是基于部门的更改。属性的描述在这里
我的要求是使用基于部门的主键获取每个属性的值,如下表所示。
老实说,我的程序中遇到了这个问题。我没有权限更改表格,也没有共同的唯一键列。如果有人能给我一个建议,我会很感激。
答案 0 :(得分:1)
{@ 3}}已添加到Oracle 9.2中,应该可以解决问题。对于其他属性,只需添加更多子查询,其中过滤器为att.attribute =' attribute2'或者'属性3' ...
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
答案 1 :(得分:1)
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
子句中
对你来说更舒服。无论如何:子查询a
从表attributes
读取数据并添加行数,
因此,对于每个部门,他们总是从1开始编号。我使用了row_number()。子查询e
联合(所有)需要属性和数字
他们因此。然后在两个子查询中生成的数字用于主连接:a.department=e.department and a.rn=e.rn
。
备选方案1 - 如果您使用的是Oracle 11g,则可以使用unpivot。查看子查询生成的内容,以及它与attributes
表的连接方式:
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的数字,然后与{{ 1}}和适当的属性
作为employees
子句中的值附加。休息的方式与原始答案类似。
case
所有三个版本都给了我相同的输出。我还在100k行的类似表上测试了第一个选项,并在几秒钟内获得输出(对于5个属性)。请测试所有解决方案并尝试理解它们。如果你可以使用unpivot版本我会更喜欢这个。 很抱歉延迟解释和任何语言错误。