我是一名经验丰富的程序员,但对SQL来说相对较新。我们正在使用Oracle 10和11.我有一个使用SQL的系统,它将实际行与虚拟行(例如“SELECT 1来自DUAL”)结合起来,根据需要进行联合和交叉,这些似乎都有效。
我的问题是我需要将这个期望数据行的系统与新数据相结合,这些数据将包含数据(简单来说就是简化)逗号分隔的字符串。
所以我认为我需要的是一种方法,将字符串转换为:“5,6,7,8”为4行,每行一列,第一行为“5”,第二行为“6”在其他语言中,我用逗号作为分隔符进行“拆分”。当然,数据并不总是有4个条目。
还有第二个问题,但我会另外提问。但我怀疑如果可能的话,如果上面的解决方案可以用作另一个SQL语句中的表(即,使用我现有的系统),它将简化一些事情。谢谢你的帮助。
答案 0 :(得分:2)
它看起来很难看,但它有效:
select r
,substr(','||csv||',',
instr(','||csv||',',',',1,r)+1,
instr(','||csv||',',',',1,r+1)-instr(','||csv||',',',',1,r)-1) v
from (select '5,6,7a,8b,,bob' csv from dual)
,(select rownum r from dual connect by level <= 4000)
where instr(csv||',',',',1,r) > 0;
R V = = 1 5 2 6 3 7a 4 8b 5 6 bob
答案 1 :(得分:1)
您应该将该逗号分隔的字符串解压缩为任何语言的外部程序,将其拆分,将其批量加载到临时表中,并在查询中使用该临时表。
如果您绝对必须在SQL中执行此操作,本文将向您介绍如何执行此操作:
http://www.oracle.com/technology/oramag/code/tips2007/070907.html
答案 2 :(得分:1)
对于SQL使用,您可以执行以下操作...
CREATE OR REPLACE TYPE tab_varchar2 AS TABLE OF VARCHAR2( 4000 );
/
CREATE OR REPLACE FUNCTION string_to_rows
( pv_string IN VARCHAR2
, pv_delimiter IN VARCHAR2 DEFAULT '_'
)
RETURN tab_varchar2
PIPELINED
AS
lv_string VARCHAR2( 32767 ) DEFAULT pv_string || pv_delimiter;
lv_num PLS_INTEGER;
BEGIN
LOOP
lv_num := INSTR( lv_string, pv_delimiter );
EXIT WHEN ( NVL( lv_num, 0 ) = 0 );
PIPE ROW( LTRIM( RTRIM( SUBSTR( lv_string, 1, lv_num - 1 ) ) ) );
lv_string := LTRIM( SUBSTR( lv_string, lv_num + 1 ) );
END LOOP;
RETURN;
END;
/
然后你可以运行这样的东西......
SELECT c.owner, c.table_name, c.column_name, c.data_type
, t.column_value column_token
FROM dba_tab_columns c
, TABLE( string_to_rows( c.column_name ) ) t
WHERE c.owner = 'SYS'
AND c.table_name = 'DBA_INDEXES'
AND c.column_name = 'AVG_LEAF_BLOCKS_PER_KEY'
哪会归还......
Row# OWNER TABLE_NAME COLUMN_NAME DATA_TYPE COLUMN_TOKEN
---- ----- ----------- ----------------------- --------- ------------
1 SYS DBA_INDEXES AVG_LEAF_BLOCKS_PER_KEY NUMBER AVG
2 SYS DBA_INDEXES AVG_LEAF_BLOCKS_PER_KEY NUMBER LEAF
3 SYS DBA_INDEXES AVG_LEAF_BLOCKS_PER_KEY NUMBER BLOCKS
4 SYS DBA_INDEXES AVG_LEAF_BLOCKS_PER_KEY NUMBER PER
5 SYS DBA_INDEXES AVG_LEAF_BLOCKS_PER_KEY NUMBER KEY