根据另一列的值选择列
Posted
技术标签:
【中文标题】根据另一列的值选择列【英文标题】:Select column based on value of another column's value 【发布时间】:2016-06-15 08:29:02 【问题描述】:我在 Oracle 数据库中有下表:
ID COLUMN_NAME FIELD1 FIELD2 FIELD3 ------------------------------------------------- 1 FIELD1 红色 蓝色 黄色 2 FIELD3 黑紫绿 3 FIELD2 灰棕白我想根据 COLUMN_NAME 的值返回 FIELD 列之一的值。
想要的结果:
ID COLUMN_NAME FIELD_VALUE --------------------------------- 1 FIELD1 红色 2 FIELD3 绿色 3 FIELD2 棕色是的,我可以使用 CASE 或 IF / THEN / ELSE 构造来做到这一点,但实际上我有大约 50 个 FIELD 列,这些列随着时间的推移会变得更多。所以这将成为一个必须维护的查询的野兽。
因此,我正在寻找一种灵活的解决方案,例如(伪代码)
SELECT ID, COLUMN_NAME, VALUE_OF_COLUMN(COLUMN_NAME) AS FIELD_VALUE FROM MYTABLE
Oracle SQL 中是否存在类似的情况不使用临时表,不重构表结构,不使用像 PL/SQL 这样的脚本?
谢谢!
【问题讨论】:
【参考方案1】:没有“灵活”的解决方案,除非您打算使用动态 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 );
【讨论】:
【参考方案2】:据我所知,Oracle 中没有这样的内置函数。您需要循环一次整个表,然后使用 dynamc sql 获取预期记录。
【讨论】:
【参考方案3】:我有类似的要求,我使用了 oracle 的 INSTR 函数
例如:INSTR(COLUMN1,COLUMN2) > 0 它返回 column2 的值在 column1 中的位置。我们可以在 WHERE 子句中使用这个条件,所以它返回所有的值。
【讨论】:
以上是关于根据另一列的值选择列的主要内容,如果未能解决你的问题,请参考以下文章