根据另一列的值选择列

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 子句中使用这个条件,所以它返回所有的值。

【讨论】:

以上是关于根据另一列的值选择列的主要内容,如果未能解决你的问题,请参考以下文章

如果存在于列表中,则根据另一列的值选择列

仅当值存在于 SQL 的另一列中时,如何选择列的值?

根据另一列的字段值选择具有相同列值的行

Scala Spark,比较两个 DataFrame 并选择另一列的值

如何根据火花DataFrame中另一列的值更改列的值

如何根据R中小标题中另一列指示的列的值添加列