【问题标题】:Select list as column in Oracle SQL在 Oracle SQL 中选择列表作为列
【发布时间】:2020-10-24 07:06:24
【问题描述】:

我想在已经存在的表中添加几行(准确地说是 15 行)。最快的方法是什么?

这可行,但似乎是多余的。

select person_id from people_table
union all
select '0010' as person_id from dual
union all
select '0019' as person_id from dual
union all
select '0085' as person_id from dual

我想知道是否有类似的解决方案:

select person_id from people_table
union all
select ('0010','0019','0085') as person_id from dual

请注意,我想为列表中的每个元素保留前导零。 This post is almost what I'm looking for,但它将每个元素转换为整数并删除前导零。

【问题讨论】:

  • “连接”是一个技术词,与您使用它的方式不同。在像计算这样的技术领域,像你这样不精确地使用语言会导致很多问题。
  • 按行连接在大量数据框库中非常常见(例如python的pandas.concat)。我不想使用join,因为这在 SQL 中具有完全不同的含义。您甚至说“技术词”是什么意思。你能想出更模棱两可的话吗?
  • 对。您在问题中想要做的是将几行“联合”(或“全部联合”)到已经存在的行集。
  • 这能回答你的问题吗? How can I select from list of values in Oracle
  • @PonderStibbons 几乎!这种语法看起来很方便,但它会将列表中的每个条目转换为数值并去掉前导零。

标签: sql oracle union-all


【解决方案1】:

您需要按如下方式使用层次结构查询:

select person_id from people_table
union all
select regexp_substr('0010,0019,0085','[^,]+',1,level) 
  from dual
connect by  level <= length (regexp_replace('0010,0019,0085', '[^,]+'))  + 1 ;

【讨论】:

  • 太棒了,这行得通。你能解释一下'[^,]+', 1, level的参数是做什么的吗?
  • 这可能有效,但请注意 OP 没有逗号分隔的输入,他确实有几个原子输入。您的解决方案假定他将首先列出聚合它们。
【解决方案2】:

您可以使用系统提供的集合类型;您可以使用 TABLE 运算符从中进行选择(即使从 Oracle 12 起不再需要,如下所示)。请注意,列名是 COLUMN_NAME - 这是 Oracle 在创建系统提供的类型时选择的名称。

让我们创建一个小表进行测试:

create table people_table (person_id varchar2(10), person_name varchar2(10));

insert into people_table (person_id, person_name) values ('2003', 'Maria');
insert into people_table (person_id, person_name) values ('2005', 'Peter');

然后,您可以按照以下方式进行操作:

select person_id from people_table
union all
select column_value from sys.odcivarchar2list('1000', '1001', '1002')
;

PERSON_ID
---------
2005
2003
1000
1001
1002

如果您不熟悉 SYS.ODCIVARCHAR2LIST(和类似的 SYS.ODCINUMBERLIST),请在 Google 上搜索;挺好用的。

【讨论】:

  • 也许值得添加,任何标量集合类型都可以,包括您自己创建的或系统中已经存在的其他集合:select * from all_coll_types where coll_type = 'TABLE' and elem_type_name = 'VARCHAR2'
【解决方案3】:

请使用正则表达式使用下面的查询,

select person_id from people_table
union all
select distinct  trim(regexp_substr(('0010,0019,0085'),'[^,]+', 1, level) ) as person_id
 from dual
 connect by regexp_substr(('0010,0019,0085'), '[^,]+', 1, level)
 order by level;

【讨论】:

  • 这可能有效,但请注意 OP 没有逗号分隔的输入,他确实有几个原子输入。您的解决方案假定他将首先列出聚合它们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-27
  • 2021-11-01
  • 1970-01-01
  • 2021-12-19
  • 2018-09-01
  • 2016-04-13
  • 1970-01-01
相关资源
最近更新 更多