我有以下要求。
Column1 Column2 Column3 Column4 Column5 Column6
Abc 02 03 02 05 07
当我选择这一行时,我应该得到如下的值
Abc 02 03 05 07 <null>
应删除重复项,但列应保持不变。
感谢您的帮助!!
谢谢, 西
答案 0 :(得分:0)
您将数据存储在应该在行中的列中。数据结构应该如下所示:
column1 number value
ABC 1 02
ABC 2 03
ABC 3 02
. . .
然后你的查询会很简单。您可以通过取消隐藏来获得所需的值:
select distinct column1, value
from (select column1, column2 as valuefrom t union all
select column1, column3 from t union all
select column1, column4 . . .
) x;
您可以使用以下方式将其作为列表获取:
select column1, listagg(value, ', ') within group (order by value)
from (select column1, column2 as valuefrom t union
select column1, column3 from t union
select column1, column4 . . .
) x
group by column1;
答案 1 :(得分:0)
行。我将所有内容(包括基表)放入一个查询中,以便其他人可以使用它 - 测试它,找到更好的方法等等。在现实生活中,我称之为&#34; t&#34; (第二个cte,或公用表表达式)是起始表,我称之为&#34; c&#34; (第一个cte)应该作为一个表或一个视图存在于某个地方,或者它可以像我一样在运行中构建。要求:表t中所有列的数量,名称和顺序必须事先知道,它们不能是动态的(除非有人想用动态SQL重写它)。
另请注意,如果我可以假设所有列名都是大写的话会容易得多。我不想假设它,所以代码看起来更复杂的上层(...) - 因为Oracle会在未透刻时将列名更改为大写(否则我将不得不做更多的工作。 ..)
我将结果返回到一个新的&#34;表&#34; format(如果t有多行,则可以使用此方法 - 输出的行数相同)。我没有在&#34;更新t ...&#34;格式;如果需要,这应该相对容易。我无法判断我是否必须改变价值观#34;意味着就位(即更新)或者如果它与输入相比在输出中意味着什么。
这是输入表(仅一行)的样子:
COLUMN1 COLUMN2 COLUMN3 COLUMN4 COLUMN5 COLUMN6
---------- ---------- ---------- ---------- ---------- ----------
Abc 02 03 02 05 07
输出:
COLUMN1 COLUMN2 COLUMN3 COLUMN4 COLUMN5 COLUMN6
---------- ---------- ---------- ---------- ---------- ----------
Abc 02 03 05 07
代码:
with c (col_rank, col_name) as (select 1, upper('Column1') from dual union all
select 2, upper('Column2') from dual union all
select 3, upper('Column3') from dual union all
select 4, upper('Column4') from dual union all
select 5, upper('Column5') from dual union all
select 6, upper('Column6') from dual ),
t (Column1, Column2, Column3, Column4, Column5, Column6) as
(select 'Abc', '02', '03', '02', '05', '07' from dual),
x as (select * from t unpivot (col_value for col_name in (Column1,
Column2, Column3, Column4, Column5, Column6))),
y as (select col_rank, col_name, col_value from x natural join c),
z as (select col_rank, col_value,
case when col_value in (select y1.col_value from y y1
where y1.col_rank < y2.col_rank) then 0
else 1 end flag from y y2),
u as (select col_value,
count(flag) over (order by col_rank rows between unbounded preceding
and current row) val_rank from z where flag = 1)
select * from (select col_name, col_value from c left outer join u
on c.col_rank = u.val_rank )
pivot (min(col_value) for col_name in (upper('Column1') Column1, upper('Column2') Column2,
upper('Column3') Column3, upper('Column4') Column4,
upper('Column5') Column5, upper('Column6') Column6))
答案 2 :(得分:0)
Oracle安装程序:
CREATE TABLE table_name ( col1, col2, col3, col4, col5, col6 ) AS
SELECT 'abc', '02', '03', '02', '05', '07' FROM DUAL UNION ALL
SELECT 'abc', '05', '04', '02', '03', '01' FROM DUAL UNION ALL
SELECT 'abc', '01', '01', '01', '01', '01' FROM DUAL;
CREATE TYPE stringlist AS TABLE OF VARCHAR2(100);
/
查询 - 未使用用户定义的功能:
SELECT MAX( col1 ) AS col1,
MAX( CASE rn WHEN 1 THEN value END ) AS col2,
MAX( CASE rn WHEN 2 THEN value END ) AS col3,
MAX( CASE rn WHEN 3 THEN value END ) AS col4,
MAX( CASE rn WHEN 4 THEN value END ) AS col5,
MAX( CASE rn WHEN 5 THEN value END ) AS col6
FROM (
SELECT col1,
rid,
ROW_NUMBER() OVER (PARTITION BY t.rid ORDER BY v.column_value) AS rn,
v.COLUMN_VALUE AS value
FROM ( SELECT col1,
ROWID AS rid,
SET( stringlist( col2, col3, col4, col5, col6 ) ) AS cols
FROM table_name ) t,
TABLE( t.cols ) v
)
GROUP BY rid;
查询 - 使用UDF :
CREATE FUNCTION nth_item(
collection STRINGLIST,
n INT
) RETURN VARCHAR2 DETERMINISTIC
AS
BEGIN
IF collection IS NULL OR n < 1 OR n > collection.COUNT THEN
RETURN NULL;
END IF;
RETURN collection(n);
END;
/
然后:
SELECT col1,
nth_item( cols, 1 ) AS col2,
nth_item( cols, 2 ) AS col3,
nth_item( cols, 4 ) AS col4,
nth_item( cols, 4 ) AS col5,
nth_item( cols, 5 ) AS col6
FROM (
SELECT col1,
SET( stringlist( col2, col3, col4, col5, col6 ) ) AS cols
FROM table_name
);
输出(针对两个查询):
COL1 COL2 COL3 COL4 COL5 COL6
---- ---- ---- ---- ---- ----
abc 02 03 05 07
abc 01 02 03 04 05
abc 01
答案 3 :(得分:0)
with
tbl as (
select 'Abc' Column1, '02' Column2, '03' Column3, '02' Column4, '03' Column5, '07' Column6, 1 rrowid from dual union all
select 'Dfg' Column1, '10' Column2, '10' Column3, '10' Column4, '10' Column5, '10' Column6, 2 rrowid from dual
),
unpv as (
select *
from tbl
unpivot (val FOR col IN (column1 AS 1, column2 AS 2, column3 AS 3, column4 AS 4, column5 as 5, column6 as 6))
),
clc as (
select rrowid, val, row_number() over (partition by rrowid order by col) col
from (
select rrowid, col,
decode(row_number() over (partition by rrowid, val order by col), 1, val, null) val
from unpv
)
where not val is null)
select * from clc
pivot (max(val) AS val FOR (col) IN (1 AS a, 2 AS b, 3 AS c, 4 as d, 5 as e, 6 as f));
结果是:
RROWID A_VAL B_VAL C_VAL D_VAL E_VAL F_VAL
---------- ----- ----- ----- ----- ----- -----
1 Abc 02 03 07
2 Dfg 10