问题:
是否可以根据其结果集中的值更改select语句中的列名?
例如,如果结果集中的year
值小于1950
,请将列命名为OldYear
,否则请将列命名为NewYear
。结果集中的year
值保证对所有记录都相同。
我认为这是不可能的,但这是我尝试测试这个想法的失败:
select 1 as
(case
when 2 = 1 then "name1";
when 1 = 1 then "name2")
from dual;
答案 0 :(得分:5)
您不能更改结果集的每一行的列名。这是关系数据库的基础。列的名称是表“header”的一部分,名称适用于其下所有行的列。
评论:好的,OP Americus可能意味着结果恰好是一行。但无论如何,SQL没有语法来支持动态列别名。列别名在查询中必须是常量。
即使动态SQL也无济于事,因为您必须运行两次查询。一次获取值,第二次使用不同的列别名重新运行查询。
答案 1 :(得分:4)
在SQL中执行此操作的“正确”方法是同时拥有两列,并使不合适的列为NULL
,例如:
SELECT
CASE WHEN year < 1950 THEN year ELSE NULL END AS OldYear,
CASE WHEN year >= 1950 THEN year ELSE NULL END AS NewYear
FROM some_table_with_years;
答案 2 :(得分:2)
没有充分的理由动态更改列名 - 它类似于过程代码中变量的名称 - 它只是您稍后可能在代码中引用的标签,因此您不希望它更改在运行时。
我猜你真正想要的是一种根据数据格式化输出(例如在报告中打印)的方法。在这种情况下,我会将标题文本生成为查询中的单独列,例如:
SELECT 1 AS mydata
,case
when 2 = 1 then 'name1'
when 1 = 1 then 'name2'
end AS myheader
FROM dual;
然后调用过程将获取为mydata和myheader返回的值,并根据需要格式化输出。
答案 3 :(得分:1)
你需要类似的东西:
select 'select ' || CASE WHEN YEAR<1950 THEN 'OLDYEAR' ELSE 'NEWYEAR' END || ' FROM TABLE 1' from TABLE_WITH_DATA
答案 4 :(得分:0)
此解决方案要求您从.bat文件或使用具有相应Oracle凭据的其他方法启动SQLPLUS和.sql文件。 .bat文件可以从服务器计划任务,Control-M作业等手动启动...
输出是.csv文件。这还要求您将输出中的所有逗号替换为输出中的某些其他字符或冒险列/数据不匹配。
技巧是在两个不同的SELECT语句中选择列标题和数据。
它并不完美,但它确实有效,并且它与我在发展环境之外的动态列标题中找到的标准Oracle SQL最接近。我们广泛使用它来为用户生成定期的每日/每周/每月报告,而无需借助GUI。输出保存到共享网络驱动器目录/ Sharepoint。
REM BEGIN runExtract1.bat file -----------------------------------------
sqlplus username/password@database @C:\DailyExtracts\Extract1.sql > C:\DailyExtracts\Extract1.log
exit
REM END runExtract1.bat file -------------------------------------------
REM BEGIN Extract1.sql file --------------------------------------------
set colsep ,
set pagesize 0
set trimspool on
set linesize 4000
column dt new_val X
select to_char(sysdate,'MON-YYYY') dt from dual;
spool c:\DailyExtracts\&X._Extract1.csv
select '&X-Project_id', 'datacolumn2-Project_Name', 'datacolumn3-Plant_id' from dual;
select
PROJ_ID
||','||
replace(PROJ_NAME,',',';')-- "Project Name"
||','||
PLANT_ID-- "Plant ID"
from PROJECTS
where ADDED_DATE >= TO_DATE('01-'||(select to_char(sysdate,'MON-YYYY') from dual));
spool off
exit
/
REM ------------------------------------------------------------------
CSV OUTPUT (opened in Excel and copy/pasted):
old 1: select '&X-Project_id' 'datacolumn2-Project_Name' 'datacolumn3-Plant_id' from dual
new 1: select 'MAR-2018-Project_id' 'datacolumn2-Project_Name' 'datacolumn3-Plant_id' from dual
MAR-2018-Project_id datacolumn2-Project_Name datacolumn3-Plant_id
31415 name1 1007
31415 name1 2032
32123 name2 3302
32123 name2 3384
32963 name3 2530
33629 name4 1161
34180 name5 1173
34180 name5 1205
...
...
etc...
135 rows selected.