Oracle 将两行合并为一行
Oracle Coalesce two rows in one
我打算将两(很多)行合并为一行。我的数据看起来像这样
╔══════════╦════════╦═══════════╦═══════════╦════════════╗
║ ReportID ║ Item ║ StartDt ║ EndDt ║ Statement ║
╠══════════╬════════╬═══════════╬═══════════╬════════════╣
║ 1 ║ 3000 ║ 11-Mar-16 ║ (null) ║ Remark ║
╠══════════╬════════╬═══════════╬═══════════╬════════════╣
║ 1 ║ 3001 ║ 11-Mar-16 ║ 13-Mar-16 ║ (null) ║
╠══════════╬════════╬═══════════╬═══════════╬════════════╣
║ 2 ║ 4002 ║ 24-May-16 ║ 27-May-16 ║ Remark1 ║
╠══════════╬════════╬═══════════╬═══════════╬════════════╣
║ 2 ║ 4003 ║ 24-May-16 ║ 28-May-16 ║ Remark1 ║
╚══════════╩════════╩═══════════╩═══════════╩════════════╝
我希望通过 ReportID
合并并使用不同的规则:
- 使用最高
endDt
- 使用
Statement
而不是 null
- 使用最高
Item
的记录中的 Statement
因此,结果应该是
╔══════════╦═══════════╦═══════════╦════════════╗
║ ReportID ║ StartDt ║ EndDt ║ Statement ║
╠══════════╬═══════════╬═══════════╬════════════╣
║ 1 ║ 11-Mar-16 ║ 13-Mar-16 ║ Remark ║
╠══════════╬═══════════╬═══════════╬════════════╣
║ 2 ║ 24-May-16 ║ 28-May-16 ║ Remark1 ║
╚══════════╩═══════════╩═══════════╩════════════╝
我需要用简单的 SQL 来实现,不能编写 PL-SQL 例程。
数据
SELECT 1 as ReportID, 3000 as Item, TO_DATE('11-03-2016') as StartDt, TO_DATE(NULL) as EndDt, 'Remark' as Statement FROM DUAL
UNION
SELECT 1, 3001, TO_DATE('11-03-2016'), TO_DATE('13-03-2016'), NULL FROM DUAL
UNION
SELECT 2, 4002, TO_DATE('24-05-2016'), TO_DATE('27-05-2016'), 'Remark1' FROM DUAL
UNION
SELECT 2, 4003, TO_DATE('24-05-2016'), TO_DATE('28-05-2016'), 'Remark1' FROM DUAL
您希望每个 reportid
占一行,因此您可以按它分组。然后使用适当的聚合函数(对语句列是 KEEP FIRST/LAST
)来获取所需的值:
select
reportid,
max(startdt) as startdt,
max(enddt) as enddt,
max(statement) keep (dense_rank last
order by case when statement is null then 1 else 2 end, item
) as statement
from mytable
group by reportid
order by reportid;
我打算将两(很多)行合并为一行。我的数据看起来像这样
╔══════════╦════════╦═══════════╦═══════════╦════════════╗
║ ReportID ║ Item ║ StartDt ║ EndDt ║ Statement ║
╠══════════╬════════╬═══════════╬═══════════╬════════════╣
║ 1 ║ 3000 ║ 11-Mar-16 ║ (null) ║ Remark ║
╠══════════╬════════╬═══════════╬═══════════╬════════════╣
║ 1 ║ 3001 ║ 11-Mar-16 ║ 13-Mar-16 ║ (null) ║
╠══════════╬════════╬═══════════╬═══════════╬════════════╣
║ 2 ║ 4002 ║ 24-May-16 ║ 27-May-16 ║ Remark1 ║
╠══════════╬════════╬═══════════╬═══════════╬════════════╣
║ 2 ║ 4003 ║ 24-May-16 ║ 28-May-16 ║ Remark1 ║
╚══════════╩════════╩═══════════╩═══════════╩════════════╝
我希望通过 ReportID
合并并使用不同的规则:
- 使用最高
endDt
- 使用
Statement
而不是null
- 使用最高
Item
的记录中的
Statement
因此,结果应该是
╔══════════╦═══════════╦═══════════╦════════════╗
║ ReportID ║ StartDt ║ EndDt ║ Statement ║
╠══════════╬═══════════╬═══════════╬════════════╣
║ 1 ║ 11-Mar-16 ║ 13-Mar-16 ║ Remark ║
╠══════════╬═══════════╬═══════════╬════════════╣
║ 2 ║ 24-May-16 ║ 28-May-16 ║ Remark1 ║
╚══════════╩═══════════╩═══════════╩════════════╝
我需要用简单的 SQL 来实现,不能编写 PL-SQL 例程。
数据
SELECT 1 as ReportID, 3000 as Item, TO_DATE('11-03-2016') as StartDt, TO_DATE(NULL) as EndDt, 'Remark' as Statement FROM DUAL
UNION
SELECT 1, 3001, TO_DATE('11-03-2016'), TO_DATE('13-03-2016'), NULL FROM DUAL
UNION
SELECT 2, 4002, TO_DATE('24-05-2016'), TO_DATE('27-05-2016'), 'Remark1' FROM DUAL
UNION
SELECT 2, 4003, TO_DATE('24-05-2016'), TO_DATE('28-05-2016'), 'Remark1' FROM DUAL
您希望每个 reportid
占一行,因此您可以按它分组。然后使用适当的聚合函数(对语句列是 KEEP FIRST/LAST
)来获取所需的值:
select
reportid,
max(startdt) as startdt,
max(enddt) as enddt,
max(statement) keep (dense_rank last
order by case when statement is null then 1 else 2 end, item
) as statement
from mytable
group by reportid
order by reportid;