Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL查询时的复杂情况_Sql_Oracle - Fatal编程技术网

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

我有如下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 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,会出现哪些无效字符如果您不想查看计数,那么您的最终查询已经只列出了这些行?