将表中的一列替换为不同表中的列并选择 *
Posted
技术标签:
【中文标题】将表中的一列替换为不同表中的列并选择 *【英文标题】:Replace one column in a table with a column in a different table and select * 【发布时间】:2012-06-28 08:35:40 【问题描述】:抱歉,标题有点令人困惑,我一直在努力寻找问题的答案,部分原因是很难在标题行中简明扼要地描述它或想出一个好的搜索字符串。 Anyhoooo,这是我面临的问题:
问题的简短版本是: 如何在 Oracle 理解的有效 SQL 中编写以下(无效但可以理解的 SQL):
select B.REPLACER as COL, A.* except A.COL from A join B on a.COL = B.COL;
这是长版(如果你已经从短版中知道我想要什么,你就不需要读这个了:P):
我的(简化的)任务是提供对表数据进行处理并将其作为子查询提供的服务。该表有很多列(几十个或更多),我坚持使用“select *”而不是一一明确列出所有列,因为没有我可以在表中添加或删除新列知道,尽管我的下游系统会知道并做出相应的调整。
比方说,这张表(以后我们称它为表A)有一个名为“COL”的列,我们需要将那个COL中的值替换为表B的REPLACER列中的值,其中两个COL值匹配。
我该怎么做?我无法重命名该列,因为下游系统需要“COL”;我不能没有“expect A.COL”部分,因为这会导致 sql 不明确。
感谢您的帮助,全能的 ***
雷
【问题讨论】:
讨论了替换列***.com/questions/729197/… 不幸的是我怀疑你的答案是否定的。 @pd40 不错的链接,我认为临时表方法是最好的方法,不优雅,但有效。 【参考方案1】:您可以使用table.*
或table.fieldName
。
table.* (except field X)
没有可用的语法。
这意味着你只能通过明确列出所有字段来获得你想要的......
select
A.field1,
A.field2,
B.field3,
A.field4,
etc
from
A join B on a.COL = B.COL;
这意味着您可能需要重新建模数据,以确保您不会不断获得新字段。 OR
写动态sql。查询数据库以找出列名,使用代码编写如上所述的查询,然后运行该动态生成的查询。
【讨论】:
也考虑了动态生成的想法。听起来没有更好的解决方案。【参考方案2】:试试这个:(未测试)
select Case B.COL
when null then A.COL
else B.REPLACER
end as COLAB, A.*
from A left join B on A.COL = B.COL;
当存在 B.COL = A.COL 时,这应该得到 B.REPLACER,您可以在选择中添加更多列(如示例 col1、col2)或使用 A.*(将 COL 更改为 COLAB 以使其与A.* 中的 A.COL)。
【讨论】:
【参考方案3】:如前所述,您不能在常规 sql 中指定不选择哪一列。您可以为此编写一个过程,但这会非常复杂,因为您需要返回一个变量表类型。可能是带有 refcursor 魔法的东西。
我能想到的最接近的方法是加入 using。这将为您提供第一个字段中的列 col 一次,其余为 a 和 b 中的所有列。所以基本上不是你想要的。 :)
select *
from a
join b using (col)
【讨论】:
【参考方案4】:让我们从第一原则开始。 select * from ....
是一个等待发生的错误,在生产代码中没有位置。当然,每个人都使用它,因为它需要更少的打字,但这并不是一个好的做法。
除此之外,ANSI SQL 标准不支持select * except col1 from ....
语法。我知道很多人希望它会,但事实并非如此。
有几种方法可以避免输入过多。一种是通过从数据字典中选择,使用像 USER_TAB_COLUMNS 这样的视图之一来生成查询。如果您需要大量这样的查询,值得编写 PL?SQL 块来执行此操作。
更简单的 hack 是使用 SQL*Plus describe
列出表 A 的结构;将其剪切'n'粘贴到支持正则表达式的 IDE 中并编辑列以提供查询的投影。
这两个选项可能会让您觉得很费力,但坦率地说,任何一种解决方法(尤其是第二种方法)都比询问 *** 花费更少的精力。下次你会知道的更好。
【讨论】:
以上是关于将表中的一列替换为不同表中的列并选择 *的主要内容,如果未能解决你的问题,请参考以下文章