下面是我需要进行查询的表的示例。
办公室表
---OFFICES----
OFFICE_ID - DEPARTMENT - EMPLOYEE_ID - MANAGER_ID
1 - ACCOUNTING - 1 - 1
2 - ACCOUNTING - 2 - 2
3 - IT - 3 - 3
员工表
---EMPLOYEES---
EMPLOYEE_ID - NAME - SURNAME
1 - JOHN - DOE
2 - JOHN2 - DOE2
3 - JOHN3 - DOE3
经理表
---MANAGERS---
MANAGER_ID - NAME - SURNAME
1 - JOHN - JONES
2 - GEORGE - GEORG
3 - ALEX - JON
我想根据OFFICES表进行查询,并根据他们所在的部门对员工和经理进行分组,但我不确定如何。例如:
---QUERY RESULTS---
ACCOUNTING - IT
JOHN DOE JOHN3 DOE
JOHN2 DOE ALEX JON
JOHN JONES
GEORGE GEOGE
答案 0 :(得分:1)
请尝试以下方法......
SELECT CASE accountingRowsFinder.name
WHEN IS NULL THEN
''
ELSE
accountingRowsFinder.name
END || ' ' || CASE accountingRowsFinder.surname
WHEN IS NULL THEN
''
ELSE
accountingRowsFinder.surname
END AS Accounting,
CASE ITRowsFinder.name
WHEN IS NULL THEN
''
ELSE
ITRowsFinder.name
END || ' ' || CASE ITRowsFinder.surname
WHEN IS NULL THEN
''
ELSE
ITRowsFinder.surname
END AS IT
FROM ( SELECT rownum AS recordNumber,
name AS name,
surname AS surname,
COUNT( * ) AS accountingCount
FROM ( SELECT name,
surname
FROM Employees
JOIN Offices ON Employees.employee_id = Offices.employee_id
AND department = 'Accounting'
UNION
SELECT name,
surname
FROM Managers
JOIN Offices ON Managers.manager_id = Offices.manager_id
AND department = 'Accounting'
) accountingNamesFinder
) accountingRowsFinder
FULL JOIN ( SELECT rownum AS recordNumber,
name AS name,
surname AS surname,
COUNT( * ) AS ITCount
FROM ( SELECT name,
surname
FROM Employees
JOIN Offices ON Employees.employee_id = Offices.employee_id
AND department = 'IT'
UNION
SELECT name,
surname
FROM Managers
JOIN Offices ON Managers.manager_id = Offices.manager_id
AND department = 'IT'
) accountingNamesFinder
) ITRowsFinder ON accountingRowsFinder.recordNumber = ITRowsFinder.recordNumber
此语句为name
中的每个surname
选择Employee
和Accounting
值,并使用{{1}将它们垂直连接到相应的Managers
列表}}。然后,为此子查询中的记录分配记录号(也称为行号)和子查询中所有记录的计数,然后返回到语句的主体。
然后执行相同的过程以形成UNION
department
的类似列表。
然后基于{{1}的值,对从我们的子查询IT
和FULL JOIN
获得的两个数据集执行FULL OUTER JOIN
(也称为accountingRowsFinder
) }}。对于那些没有相应条目的行,较长列表将为较短列表中的字段附加NULL值。
然后连接每个ITRowsFinder
的已连接数据集中的名称字段。 recordNumber
语句用于将department
值替换为空字符串以用于显示和连接目的
如果您有任何问题或意见,请随时发表评论。
进一步阅读
http://docs.oracle.com/cd/B19306_01/server.102/b14200/expressions004.htm(CASE
)
https://docs.oracle.com/cd/B19306_01/server.102/b14200/operators003.htm(在串联运算符NULL
上)
https://docs.oracle.com/cd/B19306_01/server.102/b14200/queries006.htm(加入时)
答案 1 :(得分:1)
希望这会有所帮助。我正在使用这个版本 Oracle Database 11g企业版11.2.0.3.0版 - 64位生产
select regexp_substr(ACCOUNTING, '[^;]+', 1, level) ACCOUNTING,regexp_substr(IT, '[^;]+', 1, level) IT
from (
with tmp as (
SELECT (DECODE(department, 'ACCOUNTING', empname)) ACCOUNTING
,(DECODE(department, 'IT', empname)) IT
FROM (
select distinct LISTAGG(empname, ';') WITHIN GROUP (ORDER BY department) over (partition by department) empname,department from (
select emp.name ||' '||emp.surname as empname
,ofc.department
from EMPLOYEES emp
,Offices ofc
where emp.EMPLOYEE_ID=ofc.EMPLOYEE_ID
UNION
select mgr.name||' '||mgr.surname as empname
,ofc.department
from MANAGERS mgr
,Offices ofc
where mgr.MANAGER_ID=ofc.MANAGER_ID
)
)
)
select t1.accounting , t2.it
from tmp t1, tmp t2
where t1.accounting is not null
and t2.it is not null
)
connect by level <= length(regexp_replace(accounting, '[^;]+')) + 1;