我有如下的SQL查询:
SELECT COUNT(*) FROM table t
WHERE LENGTH(TRIM(TRANSLATE(t.field, 'BWE123', ' '))) > 0
OR SUBSTR(t.field, 0, 1) IN ('0', '1')
上面的查询检查表中的字段是否不包含'BWE123'以外的值,以及第一个字符不是0还是1。 如果该字段接受除允许的查询之外的其他字符,则返回无效记录的数量。 我想扩展以上查询:
如果下面的count = 0,则应开始查询:
SELECT count(*) FROM table
如果count> 0以下查询应开始:
SELECT * FROM table t
WHERE LENGTH(TRIM(TRANSLATE(t.field, 'BWE123', ' '))) > 0
OR SUBSTR(t.field, 0, 1) IN ('0', '1')
有人知道如何创建这种查询吗?
我也知道我可以使用regexp而不是LENGTH-TRIM-TRANSLATE,我稍后将对其进行更改。
致谢
对于您的困惑,我感到抱歉,我将尽力从一开始就说明我想要实现的目标。 目前,我确实有这样的查询:
SELECT 'MY_TABLE' as TABLE, COUNT(*) AS ERROR_COUNT, 'mt.field1' AS COLUMN FROM my_table mt
WHERE LENGTH(TRIM(TRANSLATE(mt.field1, '0123456789', ' '))) > 0
OR mt.field1 IS NULL
UNION
SELECT 'MY_TABLE' as TABLE, COUNT(*) AS ERROR_COUNT, 'mt.field2' AS COLUMN FROM my_table mt
WHERE LENGTH(TRIM(TRANSLATE(mt.field2, '0123456789.-*', ' '))) > 0
OR mt.field2 IS NULL;
其执行结果在表格下方(假设表格中的field1值为'1234',那么我们有0个错误, field2的值为'a1234',所以我们有一个错误)
TABLE ERROR_COUNT COLUMN
----- ----------- ------
MY_TABLE 0 mt.field1
MY_TABLE 1 mt.field2
我以我必须测试的最小表为例,我也有包含200列或更多列的表。 我要实现的目标: 如果我们有错误(关于field2),我想创建并运行其他查询,该查询将返回到表格下方(在第二个查询结果标签中):
TABLE INVALID_CHAR COLUMN
----- ----------- ------
MY_TABLE a mt.field2
示例表(IP):
ID IP_NO PHONE
----- -------- ---------
101 192.205.230.70 +535950331
10# 192.205a.230.70 +672819233
103 192.205.230.70 +991873112
10! 192.205.230.70 +764616233
查询:
SELECT 'IP' as TABLE, COUNT(*) AS ERROR_COUNT, 'mt.ID' AS COLUMN FROM ip
WHERE LENGTH(TRIM(TRANSLATE(ip.id, '0123456789', ' '))) > 0
OR ip.id IS NULL
UNION
SELECT 'IP' as TABLE, COUNT(*) AS ERROR_COUNT, 'mt.ip_no' AS COLUMN FROM ip
WHERE LENGTH(TRIM(TRANSLATE(ip.ip_no, '0123456789.', ' '))) > 0
OR ip.ip_no IS NULL
UNION
SELECT 'IP' as TABLE, COUNT(*) AS ERROR_COUNT, 'mt.phone' AS COLUMN FROM ip
WHERE LENGTH(TRIM(TRANSLATE(ip.phone, '+0123456789', ' '))) > 0
OR ip.phone IS NULL
结果表:
TABLE ERROR_COUNT COLUMN
----- ----------- ------
IP 2 mt.id
IP 1 mt.ip_no
IP 0 mt.phone
我要创建的表:
TABLE INVALID_CHAR COLUMN
----- ----------- ------
IP # mt.id
IP ! mt.id
IP a mt.ip_no
答案 0 :(得分:0)
查询始终必须返回相同数量的列。我所看到的与您建议的最接近的是将两个查询的结果与伪列合并在一起,因此投影始终是相同的。并使用CTE减少重复。像这样:
WITH cte as (
SELECT t.field,
COUNT(*) OVER () as total_count,
CASE WHEN LENGTH(TRIM(TRANSLATE(t.field, 'BWE123', ' '))) > 0
OR SUBSTR(t.field, 0, 1) IN ('0', '1')
THEN 1
ELSE 0
END as is_invalid,
COUNT(CASE WHEN LENGTH(TRIM(TRANSLATE(t.field, 'BWE123', ' '))) > 0
OR SUBSTR(t.field, 0, 1) IN ('0', '1')
THEN 1
END) OVER () as invalid_count
FROM your_table t
)
SELECT cte.field, null as total_count
FROM cte
WHERE is_invalid = 1
UNION ALL
SELECT null, max(total_count)
FROM cte
WHERE invalid_count = 0
联合的只有一个分支可以找到任何基础数据集的任何结果。您会得到类似以下结果:
FIELD TOTAL_COUNT
------ -----------
0
1BWE23
or
FIELD TOTAL_COUNT
------ -----------
4