如何将多行组合在一行中,oracle

Posted

技术标签:

【中文标题】如何将多行组合在一行中,oracle【英文标题】:How to combine multiple rows in a single row, oracle 【发布时间】:2017-04-06 13:35:21 【问题描述】:

我有以下记录:

我想返回这样的结果:

我在加入许多表后得到了这个结果。所以仍然不知道要达到这个要求。

注意:我尝试过使用 group by,但没有成功。

查询:

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";

谢谢

【问题讨论】:

Concatenate and group multiple rows in Oracle的可能重复 你可以看看 LISTAGG 函数和 group by,将帮助你找到解决方案 查看您之前的选择,而不是事后快速而肮脏的解决方法 编辑您的问题并提供您尝试过的查询。 @Mihai 这些是分配给不同人员(VP、sup、PE 等)的相同项目。所以这是我能得到的最好的结果。我已经通过在 Java 中进行操作来显示。但问题是由于记录巨大而导致的性能问题。所以只是尝试使用查询进行选择。 【参考方案1】:
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'))'

【讨论】:

【参考方案2】:

有一个函数名LISTAGG,但在oracle 10g中不起作用。所以我们可以改用WM_CONCAT Built-in Function,这样就解决了问题。

如果您运行的不是 11g 第 2 版或更高版本,而是运行具有 WM_CONCAT 函数的数据库版本,那么它是一个零努力的解决方案,因为它会为您执行聚合。它实际上是下面描述的用户定义聚合函数的示例,但 Oracle 已经为您完成了所有工作。

但只有WM_CONCAT 功能的问题是它不会删除重复的单词。所以我们需要用DISTINCT关键字来解决问题。这是我的最终查询:

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;

【讨论】:

以上是关于如何将多行组合在一行中,oracle的主要内容,如果未能解决你的问题,请参考以下文章

如何组合多行数据,直到下一行值在 SQL Server 中不为空

如何在Access查询中将多行的文本值组合到一个单元格中[重复]

如何将每一行数据组合在一起?

如何识别有效/无效数字组合,而每个组合被拆分为多行

如何将Oracle查询结果多行数据转成一行平铺显示?

已解决:将两个变量与多行值并排组合