sql - 在管道分隔串联期间格式化列标题 (Oracle SQL)

标签 sql oracle concatenation alias sqlplus

概述:我的任务是提供从 Oracle 数据库中提取的数据作为以竖线分隔的输出文本文件。我将使用 SQLPlus 在数据所在的服务器上执行此操作。通常,这项任务并不超出我的经验,但这次,业务希望出现列标题。

考虑我需要输出的以下五列:

SELECT
    a.USER_NAME || '|'
    || a.LAST_NAME || '|'
    || a.FIRST_NAME || '|'
    || b.PRODUCT_PURCHASED || '|'
    || c.DATEPURCHASED
FROM ...
WHERE ... ;

这个 SQL 运行良好,输出如下:

omnusruthius|ruthius|omnus|stackoverflow_prod|19-APR-16

但是,企业希望它看起来像:

USER_NM|LAST|FIRST|PROD|EFFECTIVE_DATE
omnusruthius|ruthius|omnus|stackoverflow_prod|19-APR-16

问题:因此,这里的目标本质上是输出具有自定义命名的列标题(别名)的第一行,如上所示。所以我的第一个方法是尝试类似的方法:

    SELECT
    a.USER_NAME AS USER_NM || '|'
    || a.LAST_NAME AS LAST || '|'
    || a.FIRST_NAME AS FIRST || '|'
    || b.PRODUCT_PURCHASED AS PROD || '|'
    || c.DATEPURCHASED AS EFFECTIVE_DATE
    FROM ...
    WHERE ...

不幸的是,我收到:

ORA-00923: FROM keyword not found where expected

我不确定这会有什么帮助,因为没有别名的原始 SQL 输出无论如何都不会在第一行中显示列标题。请记住,这是通过命令行 (SQLPlus),而不是 Toad 或其他一些 RDMS。

然后我尝试了:

SELECT 
   'USER_NM', 'LAST', 'FIRST', 'PROD', 'EFFECTIVE_DATE' FROM DUAL
UNION ALL
SELECT
    a.USER_NAME || '|'
    || a.LAST_NAME || '|'
    || a.FIRST_NAME || '|'
    || b.PRODUCT_PURCHASED || '|'
    || c.DATEPURCHASED
FROM ...
WHERE ...

这会出现以下错误:

ORA-01789: query block has incorrect number of result columns

我感觉已经很接近解决方案了,我在这里错过了什么?任何帮助将不胜感激!

编辑:给 future 的读者一个注释,这里的两个答案都将帮助您解决这个问题,但经过进一步调整,我意识到我们都对解决方案想得太多了。我不会提出新的解决方案,因为更改是微不足道的,但请考虑执行以下操作:

SELECT 'USER_NM|LAST|FIRST|PROD|EFFECTIVE_DATE' FROM DUAL;
SELECT a.USER_NAME AS USER_NM || '|'
|| a.LAST_NAME AS LAST || '|'
|| a.FIRST_NAME AS FIRST || '|'
|| b.PRODUCT_PURCHASED AS PROD || '|'
|| c.DATEPURCHASED AS EFFECTIVE_DATE
FROM ...
WHERE ...
ORDER BY ... ;

这里的关键是 SQL*Plus 中分号的使用。第一个 SELECT 语句完全独立于第二个;不需要 UNION,因为第一个查询的输出会自动显示在第二个查询的输出之前。两者都可以有自己的规则,如果您的后一个查询要复杂得多,这会特别方便。我可以确认上面的查询正在工作,我很惊讶我花了这么长时间才意识到......

最佳答案

连接时确保 header 是单个字符串。因为您要将列中的值连接到一行上。

如果使用逗号分隔,就像问题中那样,结果 block 也应该有 5 列,但情况并非如此。

SELECT 
   'USER_NM|LAST|FIRST|PROD|EFFECTIVE_DATE' FROM DUAL
UNION ALL
SELECT
    a.USER_NAME || '|'
    || a.LAST_NAME || '|'
    || a.FIRST_NAME || '|'
    || b.PRODUCT_PURCHASED || '|'
    || c.DATEPURCHASED
FROM ...
WHERE ...

编辑:列也可以排序。

SELECT 'USER_NM|LAST|FIRST|PROD|EFFECTIVE_DATE' FROM DUAL
UNION ALL
SELECT * FROM (
SELECT
    a.USER_NAME || '|'
    || a.LAST_NAME || '|'
    || a.FIRST_NAME || '|'
    || b.PRODUCT_PURCHASED || '|'
    || c.DATEPURCHASED
FROM ...
WHERE ...
ORDER BY DATEPURCHASED) --add any other columns needed

关于sql - 在管道分隔串联期间格式化列标题 (Oracle SQL),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36723615/

相关文章:

systemverilog 中常量的串联

sql - 使用 SQL 合并记录,并遵循一些规则

sql : How is data validation done through Stored procedures?

c# - 在 C# 中将 PDF 文件从 MySQL 保存到 Oracle,中间无需任何转换

java - Oracle: ORA-00911: 无效字符

sql - 选择边界最长的州

Linux - 将文本文件的每一行与传递给函数的参数连接起来

sql - 在PL/SQL中创建或模拟二维数组

php - INNER JOIN 不返回结果

SQL Server 删除字符串中小数点后的尾随零