SQL查询时的复杂情况
我有如下SQL查询:SQL查询时的复杂情况,sql,oracle,Sql,Oracle,我有如下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。 如果字段接受允许的字符以外的字符,则查询返回无效记录的数量。 我想扩展上述查询: 如果计数=0,则应启动以下查询: SELECT
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。
如果字段接受允许的字符以外的字符,则查询返回无效记录的数量。
我想扩展上述查询:
如果计数=0,则应启动以下查询:
SELECT count(*) FROM table
SELECT * FROM table t
WHERE LENGTH(TRIM(TRANSLATE(t.field, 'BWE123', ' '))) > 0
OR SUBSTR(t.field, 0, 1) IN ('0', '1')
如果计数>0,则应启动以下查询:
SELECT count(*) FROM table
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个错误,
字段2的值为“a1234”,因此我们有一个错误)
我举一个例子,我必须测试的最小的表,我也有200或更多列的表。
我想要达到的目标:
如果我们有错误(如字段2),我想创建并运行额外的查询,返回下表(在第二个查询结果选项卡中):
示例表(IP): 查询:
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
查询始终必须返回相同数量的列。我能看到的最接近您建议的是将两个查询的结果合并在一起,使用虚拟列,以便投影总是相同的;并使用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
查询始终必须返回相同数量的列。我能看到的最接近您建议的是将两个查询的结果合并在一起,使用虚拟列,以便投影总是相同的;并使用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
不能有返回单个(数字、计数)列或多个列的查询。列数必须固定。不管怎么说,这将如何解释结果?您可以将计数附加为一个额外的列并合并结果,但不清楚您希望发生什么。实际上,现在我们可以跳过计数为0的条件。对于第二个查询,我想验证如果第一个查询中的计数大于0,会出现哪些无效字符如果您不想查看计数,那么您的最终查询已经只列出了这些行?您不能有一个返回单个(数字,计数)列或多个列的查询。列数必须固定。不管怎么说,这将如何解释结果?您可以将计数附加为一个额外的列并合并结果,但不清楚您希望发生什么。实际上,现在我们可以跳过计数为0的条件。对于第二个查询,我想验证如果第一个查询中的计数大于0,会出现哪些无效字符如果您不想查看计数,那么您的最终查询已经只列出了这些行?