如何在SQL查询中同时校验两类加密校验参数条件并返回结果?
问题描述
需要在查询中添加校验逻辑,目标参数包括:
'CRYPTO_CHECKSUM_TYPES_SERVER=(SHA256)','CRYPTO_CHECKSUM_TYPES_CLIENT=(SHA512)','CRYPTO_CHECKSUM_TYPES_SERVER=(SHA512)','CRYPTO_CHECKSUM_TYPES_CLIENT=(SHA256)'
数据包含PARAMETER字段(即上述参数名)和count_found字段(参数存在为1,不存在为0)。需求是:
- 校验
CRYPTO_CHECKSUM_TYPES_SERVER是否设置了SHA256或SHA512,两者都未设置则报告 CRYPTO_CHECKSUM_TYPES_CLIENT同理
当前查询返回结果示例:
HOST_NAME COUNT_FOUND PARAMETER FILE_CHECKED host123 0 CRYPTO_CHECKSUM_TYPES_CLIENT=(SHA256) /local/dbms/oracle/product/11.2.0.4/db_1/network/admin/sqlnet.ora host123 0 CRYPTO_CHECKSUM_TYPES_SERVER=(SHA512) /local/dbms/oracle/product/11.2.0.4/db_1/network/admin/sqlnet.ora host123 1 CRYPTO_CHECKSUM_TYPES_SERVER=(SHA256) /local/dbms/oracle/product/11.2.0.4/db_1/network/admin/sqlnet.ora host123 0 CRYPTO_CHECKSUM_TYPES_CLIENT=(SHA512) /local/dbms/oracle/product/11.2.0.4/db_1/network/admin/sqlnet.ora
原查询条件:
where (PARAMETER in ('CRYPTO_CHECKSUM_TYPES_SERVER=(SHA256)','CRYPTO_CHECKSUM_TYPES_CLIENT=(SHA512)','CRYPTO_CHECKSUM_TYPES_SERVER=(SHA512)','CRYPTO_CHECKSUM_TYPES_CLIENT=(SHA256)'))
尝试添加的新条件导致查询无结果:
where (PARAMETER in ('CRYPTO_CHECKSUM_TYPES_SERVER=(SHA256)','CRYPTO_CHECKSUM_TYPES_CLIENT=(SHA512)','CRYPTO_CHECKSUM_TYPES_SERVER=(SHA512)','CRYPTO_CHECKSUM_TYPES_CLIENT=(SHA256)')) and ((PARAMETER='CRYPTO_CHECKSUM_TYPES_CLIENT=(SHA256)' and count_found=0) and (PARAMETER='CRYPTO_CHECKSUM_TYPES_CLIENT=(SHA512)' and count_found=0))
疑问:为什么添加后无结果?如何校验不同行的两个参数?
问题原因
你添加的条件逻辑错误:同一行的PARAMETER字段不可能同时等于CRYPTO_CHECKSUM_TYPES_CLIENT=(SHA256)和CRYPTO_CHECKSUM_TYPES_CLIENT=(SHA512),用AND连接这两个条件会导致没有任何行能满足,所以返回空结果。
要校验的两个参数分别在不同行,不能用单条行的条件判断,需要按主机和参数类型(SERVER/CLIENT)分组聚合,判断该组内是否有至少一个count_found=1。
解决方案
以下提供两种可行的实现方式,以Oracle SQL为例:
方法1:分组聚合统计
先提取参数类型(SERVER/CLIENT),然后按主机、参数类型分组,统计该类型下是否有已设置的参数:
SELECT HOST_NAME, CASE WHEN SUBSTR(PARAMETER, 1, INSTR(PARAMETER, '_TYPE_') + 5) = 'CRYPTO_CHECKSUM_TYPES_SERVER' THEN 'SERVER' ELSE 'CLIENT' END AS PARAM_TYPE, FILE_CHECKED, MAX(count_found) AS has_valid_setting FROM your_table_name WHERE PARAMETER IN ( 'CRYPTO_CHECKSUM_TYPES_SERVER=(SHA256)', 'CRYPTO_CHECKSUM_TYPES_CLIENT=(SHA512)', 'CRYPTO_CHECKSUM_TYPES_SERVER=(SHA512)', 'CRYPTO_CHECKSUM_TYPES_CLIENT=(SHA256)' ) GROUP BY HOST_NAME, CASE WHEN SUBSTR(PARAMETER, 1, INSTR(PARAMETER, '_TYPE_') + 5) = 'CRYPTO_CHECKSUM_TYPES_SERVER' THEN 'SERVER' ELSE 'CLIENT' END, FILE_CHECKED HAVING MAX(count_found) = 0; -- 只返回该类型下两个参数都未设置的记录
方法2:窗口函数标记
用窗口函数按主机和参数类型计算是否有有效设置,再筛选出无效的记录:
WITH param_groups AS ( SELECT HOST_NAME, PARAMETER, FILE_CHECKED, count_found, MAX(count_found) OVER ( PARTITION BY HOST_NAME, CASE WHEN PARAMETER LIKE 'CRYPTO_CHECKSUM_TYPES_SERVER%' THEN 'SERVER' ELSE 'CLIENT' END, FILE_CHECKED ) AS group_has_valid FROM your_table_name WHERE PARAMETER IN ( 'CRYPTO_CHECKSUM_TYPES_SERVER=(SHA256)', 'CRYPTO_CHECKSUM_TYPES_CLIENT=(SHA512)', 'CRYPTO_CHECKSUM_TYPES_SERVER=(SHA512)', 'CRYPTO_CHECKSUM_TYPES_CLIENT=(SHA256)' ) ) SELECT HOST_NAME, PARAMETER, FILE_CHECKED, count_found FROM param_groups WHERE group_has_valid = 0; -- 返回该类型下两个参数都未设置的所有行
说明
- 两种方法都会按
HOST_NAME和参数类型(SERVER/CLIENT)聚合判断:如果该类型下的两个参数count_found都是0,就会被筛选出来 - 方法1返回每个主机+参数类型的汇总记录,方法2返回所有符合条件的明细行,可根据需求选择
内容的提问来源于stack exchange,提问作者Roshni Rabi
相关产品推荐
相关产品推荐

