如何检查每条记录是否有多个列不为空?

时间:2018-05-16 19:35:20

标签: sql oracle

我有一个包含4个字段ethn_1,ethn_2,ethn_3和ethn_4的表。

我需要将这四个字段用于:

  1. 将v_ethn_code变量设置为只有其中一个字段包含值时存储的种族。
  2. 如果其中多个列包含值,则将v_ethn_code变量设置为“未知”。
  3. 示例数据: https://imgur.com/a/El5TRWB

    CREATE TABLE users
    ( id number(4) NOT NULL,
      ethn_1 varchar2(3),
      ethn_2 varchar2(3),
      ethn_3 varchar2(3),
      ethn_4 varchar2(3),
    );
    
    INSERT INTO users (id, ethn_1, ethn_2, ethn_3, ethn_4) VALUES (1,'AS',NULL,NULL,NULL);
    INSERT INTO users (id, ethn_1, ethn_2, ethn_3, ethn_4) VALUES (2,NULL,NULL,'WH',NULL);
    INSERT INTO users (id, ethn_1, ethn_2, ethn_3, ethn_4) VALUES (3,NULL,'BL',NULL,NULL);
    INSERT INTO users (id, ethn_1, ethn_2, ethn_3, ethn_4) VALUES (4,'AS','BL',NULL,NULL);
    INSERT INTO users (id, ethn_1, ethn_2, ethn_3, ethn_4) VALUES (5,NULL,NULL,NULL,'HO');
    INSERT INTO users (id, ethn_1, ethn_2, ethn_3, ethn_4) VALUES (6,NULL,NULL,'WH','HO');
    INSERT INTO users (id, ethn_1, ethn_2, ethn_3, ethn_4) VALUES (7,NULL,'BL',NULL,NULL);
    
    
    ╔════╤════════╤════════╤════════╤════════╗
    ║ id │ ethn_1 │ ethn_2 │ ethn_3 │ ethn_4 ║
    ╠════╪════════╪════════╪════════╪════════╣
    ║ 1  │ AS     │        │        │        ║
    ╟────┼────────┼────────┼────────┼────────╢
    ║ 2  │        │        │ WH     │        ║
    ╟────┼────────┼────────┼────────┼────────╢
    ║ 3  │        │ BL     │        │        ║
    ╟────┼────────┼────────┼────────┼────────╢
    ║ 4  │ AS     │ BL     │        │        ║
    ╟────┼────────┼────────┼────────┼────────╢
    ║ 5  │        │        │        │ HO     ║
    ╟────┼────────┼────────┼────────┼────────╢
    ║ 6  │        │        │ WH     │ HO     ║
    ╟────┼────────┼────────┼────────┼────────╢
    ║ 7  │        │ BL     │        │        ║
    ╚════╧════════╧════════╧════════╧════════╝
    

    我已经尝试嵌套条件来说明如果ethn_1不为null,将其设置为this,然后检查ethn_2是否为null,返回并将变量设置为unknown等等...但这不符合逻辑,并且会比我认为更有效的代码更多。检查这个的正确方法是什么?

3 个答案:

答案 0 :(得分:1)

不是最漂亮的,但你可以使用一个案例来查找空值,当不为1时为1然后coalese显示单个值,否则为未知。

With CTE (Ethn_1, Ethn_2, Ethn_3, Ethn_4) as (
Select 'AS', Null,null,null from dual union all
select null,null,'WH',null from dual union all
select null,'BL',null,null from dual union all
select 'AS','BL',NULL,null from dual union all
select null,null,null,'HO' from dual union all
select null,null,'WH','HO' from dual union all
select null,'BL',null,'HO' from dual)

Select A.*, Case when (Case when Ethn_1 is not null then 1 else 0 end +
                       Case when Ethn_2 is not null then 1 else 0 end+
                       Case when Ethn_3 is not null then 1 else 0 end+
                       Case when Ethn_4 is not null then 1 else 0 end) = 1 
                 then coalesce(Ethn_1, Ethn_2, Ethn_3, Ethn_4) 
                 else 'UNKNOWN' end AS v_ethn_code 
from cte A;

或检查是否为空并计数3

Select A.*, Case when (case when Ethn_1 is null then 1 else 0 end+
                       Case when Ethn_2 is null then 1 else 0 end+
                       Case when Ethn_3 is null then 1 else 0 end+
                       Case when Ethn_4 is null then 1 else 0 end) = 3
                 then coalesce(Ethn_1, Ethn_2, Ethn_3, Ethn_4) 
                 else 'UNKNOWN' end AS v_ethn_code
from cte A;

我无法找到一个导致1.0检查的函数,这将避免使用case语句。

导致:

+--------+--------+--------+--------+-------------+
| ETHN_1 | ETHN_2 | ETHN_3 | ETHN_4 | V_ETHN_CODE |
+--------+--------+--------+--------+-------------+
| AS     |        |        |        | AS          |
|        |        | WH     |        | WH          |
|        | BL     |        |        | BL          |
| AS     | BL     |        |        | UNKNOWN     |
|        |        |        | HO     | HO          |
|        |        | WH     | HO     | UNKNOWN     |
|        | BL     |        | HO     | UNKNOWN     |
+--------+--------+--------+--------+-------------+

答案 1 :(得分:1)

尝试这样的事情:

Module

答案 2 :(得分:0)

试试这个 -

http://sqlfiddle.com/#!4/817c0f/2/0

CREATE TABLE ETHN
    (ID INT, ETHN_1 VARCHAR2(6), ETHN_2 VARCHAR2(6), ETHN_3 VARCHAR2(6), ETHN_4 VARCHAR2(6))
;

INSERT ALL 
    INTO ETHN (ID, ETHN_1, ETHN_2, ETHN_3, ETHN_4)
         VALUES (1, 'AS', NULL, NULL, NULL)
    INTO ETHN (ID, ETHN_1, ETHN_2, ETHN_3, ETHN_4)
         VALUES (2, NULL, NULL, 'WH', NULL)
    INTO ETHN (ID, ETHN_1, ETHN_2, ETHN_3, ETHN_4)
         VALUES (3, NULL, 'BL', NULL, NULL)
    INTO ETHN (ID, ETHN_1, ETHN_2, ETHN_3, ETHN_4)
         VALUES (4, 'AS', 'BL', NULL, NULL)
    INTO ETHN (ID, ETHN_1, ETHN_2, ETHN_3, ETHN_4)
         VALUES (5, NULL, NULL, NULL, 'BO')
SELECT * FROM DUAL
;
  

查询 -

SELECT STR, CASE WHEN CNT = 3 THEN RESULT ELSE 'UNKNOWN' END AS V_ETHN_CODE FROM (
SELECT STR, REGEXP_REPLACE(STR, ',*NA,*','') AS RESULT, REGEXP_COUNT(STR,'NA') AS CNT FROM (
SELECT NVL(ETHN_1,'NA') ||',' || NVL(ETHN_2,'NA') ||',' || NVL(ETHN_3,'NA') ||',' || NVL(ETHN_4,'NA') AS STR
FROM ETHN
  ));
  

输出

STR             V_ETHN_CODE
AS,NA,NA,NA     AS
NA,NA,WH,NA     WH
NA,BL,NA,NA     BL
AS,BL,NA,NA     UNKNOWN
NA,NA,NA,BO     BO