我的任务是编写一个PL/SQL查询,在成员不符合数据质量标准的情况下提供错误状态.例如,如果某个成员的名字短于3个字符,则Case语句将返回该成员,并显示"Forename Too Short".然后,我需要将该成员包括在下一个 case 陈述中"名字不能等于姓氏",然后是最后一个 case 陈述"成员低于法定工作年龄". 目前的情况是,如果会员没有通过第一次判断,那么他们就不会被包括在其他判断中.我需要我的查询潜在地返回一个成员3次,说明每次返回的原因.

SELECT 
  member_code,
  CASE
    WHEN LENGTH(forename) < 3 THEN 'Forename less than 3 characters'
    WHEN date_of_birth > TO_DATE('31/01/2008', 'DD/MM/YYYY') THEN 'Date of birth after 31/01/2008'
    WHEN forename = surname THEN 'Forename is equal to surname'
    ELSE 'No error'
  END AS error_status
FROM your_table_name;

推荐答案

在Oracle 12中,您可以使用LATERAL联接:

SELECT member_code,
       error_status
FROM   your_table_name
       CROSS JOIN LATERAL (
         SELECT 'Forename less than 3 characters' AS error_status,
                1 AS priority
         FROM   DUAL
         WHERE  LENGTH(forename) < 3
         UNION ALL
         SELECT 'Date of birth after 31/01/2008' AS error_status,
                1 AS priority
         FROM   DUAL
         WHERE  date_of_birth > DATE '2008-01-31'
         UNION ALL
         SELECT 'Forename is equal to surname' AS error_status,
                1 AS priority
         FROM   DUAL
         WHERE forename = surname
         UNION ALL
         SELECT 'No Error' AS error_status,
                2 AS priority
         FROM   DUAL
         ORDER BY priority
         FETCH FIRST ROW WITH TIES
       );

在早期版本中,您可以使用多个CASE表达式,然后使用UNPIVOT表达式将列转换为行:

SELECT member_code,
       error_status
FROM   (
  SELECT member_code,
         err1,
         err2,
         err3,
         CASE 
         WHEN err1 IS NULL AND err2 IS NULL AND err3 IS NULL
         THEN 'No Error'
         END AS no_error
  FROM   (
    SELECT member_code,
           CASE WHEN LENGTH(forename) < 3 THEN 'Forename less than 3 characters' END
             AS err1,
           CASE WHEN date_of_birth > DATE '2008-01-31' THEN 'Date of birth after 31/01/2008' END
             AS err2,
           CASE WHEN forename = surname THEN 'Forename is equal to surname' END
             AS err3
    FROM   your_table_name
  )
)
UNPIVOT (error_status FOR type IN (err1, err2, err3, no_error));

其中,对于样本数据:

CREATE TABLE your_table_name (member_code, forename, surname, date_of_birth) AS
SELECT 1, 'Ng',     'Ng',     DATE '2010-01-01' FROM DUAL UNION ALL
SELECT 2, 'Thomas', 'Thomas', DATE '2008-01-01' FROM DUAL UNION ALL
SELECT 3, 'Alice',  'Abbot',  DATE '1970-01-01' FROM DUAL;

两个输出:

MEMBER_CODE ERROR_STATUS
1 Forename less than 3 characters
1 Date of birth after 31/01/2008
1 Forename is equal to surname
2 Forename is equal to surname
3 No Error

fiddle

Sql相关问答推荐

SQL—如何根据2列填写缺失的值

在多个柱上连接时,如何确定连接条件?

分组多输出访问查询问题

如何更新SQLite数据库中的表?

PostgreSQL基于2个COLS的任意组合 Select 唯一行

重新组合已排序的日期范围

在Oracle SQL中将列值转换为行

获得第三名或最老的记录

SQL:如何在表中同时使用GROUPING和CONDITION?

SQL Athena/prest判断值是否在嵌套的json数组中

根据时间、状态和相关行在PostgreSQL中的存在来删除行

Athena 计算从日期到当前时间戳的每月计数

计算不同模式的时间跨度

Select 一个非零值减少重复

什么是 100.它与 100 有什么区别?

为什么在事务中未被后续使用的CTE执行SELECT...FOR UPDATE无效?

如何更改 duckdb R 中的数据约束

SQL查询以获取从特定可变日期看到的用户

SQL - 使用子查询返回多行的 LIKE 命令

如何优化sql请求?