How to combine multiple rows in a single row, orac

2019-09-14 16:05发布

I have following record:

enter image description here

And I want to return result like this:

enter image description here

I have got this result after joining many tables. So still no idea to achieve this requirement.

Note: I have tried with group by but didn't work.

Query:

SELECT 
P.CODE AS "projectNumber", 
P.NAME AS "projectName", 
P.START_DATE AS "startDate", 
P.END_DATE AS "endDate",
TRIM (VP.firstName || ' ' || VP.lastName) AS "vp",
TRIM (SRPM.firstName || ' ' || SRPM.lastName) AS "srpm",
TRIM (PM.firstName || ' ' || PM.lastName) AS "pm",
TRIM (SUP.firstName || ' ' || SUP.lastName) AS "sup",
TRIM (PE.firstName || ' ' || PE.lastName) AS "pe"
FROM DA.ROJECT_TABLE P
LEFT JOIN BA.teams_v VP on (P.CODE=VP.projectnumber and VP.code not in ('30', '85', 'ZZ') and VP.employoeenumber is not null and VP.status='A' and VP.projectrolename in ('Sr. Vice President, CFO','Senior Vice President','Vice President','President','Sr. Vice President','Vice President of Operations','Vice President', 'Chief Estimator','Vice President, Senior Project Manager','Vice President of Preconstruction and Estimating','Executive Vice President','Vice President, Sr. Project Manager'))
LEFT JOIN BA.teams_v SRPM on (P.CODE=SRPM.projectnumber and SRPM.code not in ('30', '85', 'ZZ') and SRPM.employoeenumber is not null and SRPM.status='A' and SRPM.projectrolename in ('Vice President/Sr. Project Manager','Senior Project Manager','Vice President, Senior Project Manager','Vice President, Sr. Project Manager'))
LEFT JOIN BA.teams_v PM on (P.CODE=PM.projectnumber and PM.code not in ('30', '85', 'ZZ') and PM.employoeenumber is not null and PM.status='A' and PM.projectrolename in ('Project Manager','Assistant Project Manager','Manager, Project Accounting','Asst. Project Manager'))
LEFT JOIN BA.teams_v SUP on (P.CODE=SUP.projectnumber and SUP.code not in ('30', '85', 'ZZ') and SUP.employoeenumber is not null and SUP.status='A' and SUP.projectrolename in ('Assistant Superintendent','CMatt - Superintendent','General Superintendent'))
LEFT JOIN BA.teams_v PE on (P.CODE=PE.projectnumber and PE.code not in  ('30', '85', 'ZZ') and PE.employoeenumber is not null and PE.status='A' and PE.projectrolename in ('Senior Project Engineer','Sr. Project Engineer','Intern Asst. Project Engineer','Assistant Project Engineer','Intern Project Engineer','Project Engineer'))
WHERE P.PMP_COMP_CODE NOT IN ('30', '85', 'ZZ')AND P.STATUS_CODE NOT IN ('CLOSED') AND P.PCODE='ALL' AND NVL(LENGTH(TRIM(TRANSLATE(substr(P.CODE, 1, 1), ' +-.012*34-56+789LP', ' '))),'0') = 0 ORDER BY "projectNumber";

Thank you

2条回答
疯言疯语
2楼-- · 2019-09-14 16:44

There is a function name LISTAGG, but it doesn't work in oracle 10g. So we can use WM_CONCAT Built-in Function instead and it solves the problem.

If you are not running 11g Release 2 or above, but are running a version of the database where the WM_CONCAT function is present, then it is a zero effort solution as it performs the aggregation for you. It is actually an example of a user defined aggregate function described below, but Oracle have done all the work for you.

But the problem with only WM_CONCAT function is it does not remove duplicate words. So we need to use it with DISTINCT keyword and problem solves. Here is my final query:

SELECT 
P.CODE AS "projectNumber", 
P.NAME AS "projectName", 
P.START_DATE AS "startDate", 
P.END_DATE AS "endDate",
WM_CONCAT(DISTINCT TRIM (VP.firstName || ' ' || VP.lastName)) AS "vp",
WM_CONCAT(DISTINCT TRIM (SRPM.firstName || ' ' || SRPM.lastName)) AS "srpm",
WM_CONCAT(DISTINCT TRIM (PM.firstName || ' ' || PM.lastName)) AS "pm",
WM_CONCAT(DISTINCT TRIM (SUP.firstName || ' ' || SUP.lastName)) AS "sup",
WM_CONCAT(DISTINCT TRIM (PE.firstName || ' ' || PE.lastName)) AS "pe"
FROM DA.ROJECT_TABLE P
LEFT JOIN BA.teams_v VP on (P.CODE=VP.projectnumber and VP.code not in ('30', '85', 'ZZ') and VP.employoeenumber is not null and VP.status='A' and VP.projectrolename in ('Sr. Vice President, CFO','Senior Vice President','Vice President','President','Sr. Vice President','Vice President of Operations','Vice President', 'Chief Estimator','Vice President, Senior Project Manager','Vice President of Preconstruction and Estimating','Executive Vice President','Vice President, Sr. Project Manager'))
LEFT JOIN BA.teams_v SRPM on (P.CODE=SRPM.projectnumber and SRPM.code not in ('30', '85', 'ZZ') and SRPM.employoeenumber is not null and SRPM.status='A' and SRPM.projectrolename in ('Vice President/Sr. Project Manager','Senior Project Manager','Vice President, Senior Project Manager','Vice President, Sr. Project Manager'))
LEFT JOIN BA.teams_v PM on (P.CODE=PM.projectnumber and PM.code not in ('30', '85', 'ZZ') and PM.employoeenumber is not null and PM.status='A' and PM.projectrolename in ('Project Manager','Assistant Project Manager','Manager, Project Accounting','Asst. Project Manager'))
LEFT JOIN BA.teams_v SUP on (P.CODE=SUP.projectnumber and SUP.code not in ('30', '85', 'ZZ') and SUP.employoeenumber is not null and SUP.status='A' and SUP.projectrolename in ('Assistant Superintendent','CMatt - Superintendent','General Superintendent'))
LEFT JOIN BA.teams_v PE on (P.CODE=PE.projectnumber and PE.code not in  ('30', '85', 'ZZ') and PE.employoeenumber is not null and PE.status='A' and PE.projectrolename in ('Senior Project Engineer','Sr. Project Engineer','Intern Asst. Project Engineer','Assistant Project Engineer','Intern Project Engineer','Project Engineer'))
WHERE P.PMP_COMP_CODE NOT IN ('30', '85', 'ZZ')AND P.STATUS_CODE NOT IN ('CLOSED') AND P.PCODE='ALL' AND NVL(LENGTH(TRIM(TRANSLATE(substr(P.CODE, 1, 1), ' +-.012*34-56+789LP', ' '))),'0') = 0
GROUP BY P.CODE, P.NAME, P.START_DATE, P.END_DATE;
查看更多
男人必须洒脱
3楼-- · 2019-09-14 16:57
Try this ...



'SELECT distinct
P.CODE AS "projectNumber", 
P.NAME AS "projectName", 
P.START_DATE AS "startDate", 
P.END_DATE AS "endDate",

LISTAGG((VP.firstName || ' ' || VP.lastName), ' ') WITHIN GROUP (order by rownum) AS VP,
TRIM (SRPM.firstName || ' ' || SRPM.lastName) AS "srpm",
TRIM (PM.firstName || ' ' || PM.lastName) AS "pm",
TRIM (SUP.firstName || ' ' || SUP.lastName) AS "sup",
TRIM (PE.firstName || ' ' || PE.lastName) AS "pe"
FROM DA.ROJECT_TABLE P
LEFT JOIN BA.teams_v VP on (P.CODE=VP.projectnumber and VP.code not in ('30', '85', 'ZZ') and VP.employoeenumber is not null and VP.status='A' and VP.projectrolename in ('Sr. Vice President, CFO','Senior Vice President','Vice President','President','Sr. Vice President','Vice President of Operations','Vice President', 'Chief Estimator','Vice President, Senior Project Manager','Vice President of Preconstruction and Estimating','Executive Vice President','Vice President, Sr. Project Manager'))
LEFT JOIN BA.teams_v SRPM on (P.CODE=SRPM.projectnumber and SRPM.code not in ('30', '85', 'ZZ') and SRPM.employoeenumber is not null and SRPM.status='A' and SRPM.projectrolename in ('Vice President/Sr. Project Manager','Senior Project Manager','Vice President, Senior Project Manager','Vice President, Sr. Project Manager'))
LEFT JOIN BA.teams_v PM on (P.CODE=PM.projectnumber and PM.code not in ('30', '85', 'ZZ') and PM.employoeenumber is not null and PM.status='A' and PM.projectrolename in ('Project Manager','Assistant Project Manager','Manager, Project Accounting','Asst. Project Manager'))
LEFT JOIN BA.teams_v SUP on (P.CODE=SUP.projectnumber and SUP.code not in ('30', '85', 'ZZ') and SUP.employoeenumber is not null and SUP.status='A' and SUP.projectrolename in ('Assistant Superintendent','CMatt - Superintendent','General Superintendent'))
LEFT JOIN BA.teams_v PE on (P.CODE=PE.projectnumber and PE.code not in  ('30', '85', 'ZZ') and PE.employoeenumber is not null and PE.status='A' and PE.projectrolename in ('Senior Project Engineer','Sr. Project Engineer','Intern Asst. Project Engineer','Assistant Project Engineer','Intern Project Engineer','Project Engineer'))'
查看更多
登录 后发表回答