SQL 如果任何相关客户失败,则检查失败的逻辑

SQL logic to fail a check if any of the related customers has failed

我有要求只有当所有相关客户也都通过检查时才标记客户Y。 下面是两个 tables:

关系table:

customer_id related_customer
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
11 11
11 22
22 11
22 22

勾选table

customer_id check_flag
1 y
2 y
3 n
11 y
22 y

我想要如下输出:

customer_id  paas_fail_flag
1 n
2 n
3 n
11 y
22 y

输出理由:由于 1,2,3 是相关客户,并且其中一个 (3) 在 table 2 中有 n 个,因此所有相关客户也应该有 n 个。 11,22 是相关客户并且在 table 2.so 中都有 y 在输出中都应该有 y.

是这样的吗?第 1 - 40 行中的示例数据;查询从第 41 行开始:

SQL> WITH
  2     -- sample data
  3     rel (customer_id, related_customer)
  4     AS
  5        (SELECT 1, 1 FROM DUAL
  6         UNION ALL
  7         SELECT 1, 2 FROM DUAL
  8         UNION ALL
  9         SELECT 1, 3 FROM DUAL
 10         UNION ALL
 11         SELECT 2, 1 FROM DUAL
 12         UNION ALL
 13         SELECT 2, 2 FROM DUAL
 14         UNION ALL
 15         SELECT 2, 3 FROM DUAL
 16         UNION ALL
 17         SELECT 3, 1 FROM DUAL
 18         UNION ALL
 19         SELECT 3, 2 FROM DUAL
 20         UNION ALL
 21         SELECT 3, 3 FROM DUAL
 22         UNION ALL
 23         SELECT 11, 11 FROM DUAL
 24         UNION ALL
 25         SELECT 11, 22 FROM DUAL
 26         UNION ALL
 27         SELECT 22, 11 FROM DUAL
 28         UNION ALL
 29         SELECT 22, 22 FROM DUAL),
 30     chk (customer_id, check_flag)
 31     AS
 32        (SELECT 1, 'y' FROM DUAL
 33         UNION ALL
 34         SELECT 2, 'y' FROM DUAL
 35         UNION ALL
 36         SELECT 3, 'n' FROM DUAL
 37         UNION ALL
 38         SELECT 11, 'y' FROM DUAL
 39         UNION ALL
 40         SELECT 22, 'y' FROM DUAL),

 41     temp
 42     AS
 43     -- minimum CHECK_FLAG per customer and related customer
 44        (  SELECT r.customer_id, r.related_customer, MIN (c.check_flag) mcf
 45             FROM rel r JOIN chk c ON c.customer_id = r.related_customer
 46         GROUP BY r.customer_id, r.related_customer)
 47    SELECT customer_id, MIN (mcf) flag
 48      FROM temp
 49  GROUP BY customer_id
 50  ORDER BY customer_id;

CUSTOMER_ID FLAG
----------- ----
          1 n
          2 n
          3 n
         11 y
         22 y

SQL>

您需要加入 relationshipcheck 并使用条件聚合:

SELECT r.customer_id,
       COALESCE(MAX(CASE WHEN c.check_flag = 'n' THEN c.check_flag END), 'y') paas_fail_flag  
FROM relationship r INNER JOIN "check" c 
ON c.customer_id = r.related_customer
GROUP BY r.customer_id
ORDER BY r.customer_id

参见demo

假设您的关系数据可能是稀疏的,例如:

CREATE TABLE relationship ( customer_id, related_customer ) AS
SELECT  2,  3 FROM DUAL UNION ALL
SELECT  3,  1 FROM DUAL UNION ALL
SELECT  3,  2 FROM DUAL UNION ALL
SELECT 11, 22 FROM DUAL;

CREATE TABLE "CHECK" ( customer_id, check_flag ) AS
SELECT  1, 'y' FROM DUAL UNION ALL
SELECT  2, 'y' FROM DUAL UNION ALL
SELECT  3, 'n' FROM DUAL UNION ALL
SELECT 11, 'y' FROM DUAL UNION ALL
SELECT 22, 'y' FROM DUAL;

(注意:以下查询也适用于您的密集数据,其中枚举了每个关系组合。)

然后就可以使用分层查询了:

SELECT customer_id,
       MIN(check_flag) AS check_flag
FROM   (
  SELECT CONNECT_BY_ROOT(c.customer_id) AS customer_id,
         c.check_flag AS check_flag
  FROM   "CHECK" c
         LEFT OUTER JOIN relationship r
         ON (r.customer_id = c.customer_id)
  WHERE  CONNECT_BY_ISLEAF = 1
  CONNECT BY NOCYCLE
         (  PRIOR r.related_customer = c.customer_id
         OR PRIOR c.customer_id = r.related_customer )
  AND    PRIOR c.check_flag = 'y'
)
GROUP BY
       customer_id
ORDER BY
       customer_id

输出:

CUSTOMER_ID CHECK_FLAG
1 n
2 n
3 n
11 y
22 y

db<>fiddle here