我在Oracle数据库中有以下表格:
ID COLUMN_NAME FIELD1 FIELD2 FIELD3 ------------------------------------------------- 1 FIELD1 red blue yellow 2 FIELD3 black purple green 3 FIELD2 grey brown white
我想根据COLUMN_NAME的值返回其中一个FIELD列的值。
期望的结果:
ID COLUMN_NAME FIELD_VALUE --------------------------------- 1 FIELD1 red 2 FIELD3 greeen 3 FIELD2 brown
是的,我可以使用CASE或IF / THEN / ELSE结构来实现这一点,但实际上我有大约50个FIELD列随着时间的推移会变得越来越多。因此,这将成为一个必须维护的查询的野兽。
因此,我正在寻找一种灵活的解决方案,如(伪代码)
SELECT ID, COLUMN_NAME, VALUE_OF_COLUMN(COLUMN_NAME) AS FIELD_VALUE FROM MYTABLE
在没有的Oracle SQL 中使用临时表,没有重构表结构,没有使用脚本如PL / SQL ?
谢谢!
答案 0 :(得分:4)
没有"灵活的"除非您打算使用动态SQL来获取每个值(这可能会严重降低性能)。
您可以使用CASE
:
CASE column_name
WHEN 'FIELD1' THEN field1
WHEN 'FIELD2' THEN field2
WHEN 'FIELD3' THEN field3
ELSE 'default'
END AS field_value
或DECODE
:
DECODE( column_name, 'FIELD1', field1, 'FIELD2', field2, 'FIELD3', field3, 'default' )
AS field_value
或通过取消旋转表格。但是,如果更改列数,则所有这些解决方案都需要更新。
另一种方法是重构你的表:
CREATE TABLE field_values (
id INT,
field_name VARCHAR2(20),
field_value VARCHAR2(20),
CONSTRAINT field_values__id_fn__pk PRIMARY KEY ( id, field_name )
);
CREATE TABLE ids (
id INT PRIMARY KEY,
column_name VARCHAR2(20),
CONSTRAINT ids__id_cn__fk FOREIGN KEY ( id, column_name )
REFERENCES field_names ( id, field_name )
);
INSERT INTO field_names
SELECT 1, 'FIELD1', 'red' FROM DUAL UNION ALL
SELECT 1, 'FIELD2', 'blue' FROM DUAL UNION ALL
SELECT 1, 'FIELD3', 'yellow' FROM DUAL UNION ALL
SELECT 2, 'FIELD1', 'black' FROM DUAL UNION ALL
SELECT 2, 'FIELD2', 'purple' FROM DUAL UNION ALL
SELECT 2, 'FIELD3', 'green' FROM DUAL UNION ALL
SELECT 3, 'FIELD1', 'grey' FROM DUAL UNION ALL
SELECT 3, 'FIELD2', 'brown' FROM DUAL UNION ALL
SELECT 3, 'FIELD3', 'white' FROM DUAL;
INSERT INTO ids
SELECT 1, 'FIELD1' FROM DUAL UNION ALL
SELECT 2, 'FIELD3' FROM DUAL UNION ALL
SELECT 3, 'FIELD2' FROM DUAL;
SELECT i.id,
i.column_name,
f.field_value
FROM ids i
INNER JOIN field_values f
ON ( i.id = f.id AND i.column_name = f.field_name );
答案 1 :(得分:0)
据我所知,Oracle中没有这样的内置功能。您需要在整个表中循环一次,然后使用dynamc sql获取预期记录。
答案 2 :(得分:0)
我有类似的需求,我使用了 oracle 的 INSTR 函数
例如:INSTR(COLUMN1,COLUMN2) > 0 它返回 column2 值在 column1 中的位置。我们可以在 WHERE 子句中使用这个条件,因此它返回所有值。