将2个SQL查询合并为一个查询

将2个SQL查询合并为一个查询,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,有人能帮我把两个查询合并成一个吗? 基本上是相同的查询,有不同的子句(请注意子查询中的FIELD3筛选器和相关计数器): 我的目标是什么?让我解释清楚。 我有一个带有一些字段的表的Oracle DB,对于这个查询,只需要3个字段,如下所示。 我正在尝试使用多个计数进行查询。我需要的是一个查询,根据FIELD3的前5位,输出一个超过特定计数的列表。让我举一个具体的例子: 这就是我在DB中所做的: FIELD1 FIELD2 FIELD3

有人能帮我把两个查询合并成一个吗? 基本上是相同的查询,有不同的子句(请注意子查询中的FIELD3筛选器和相关计数器):

我的目标是什么?让我解释清楚。 我有一个带有一些字段的表的Oracle DB,对于这个查询,只需要3个字段,如下所示。 我正在尝试使用多个计数进行查询。我需要的是一个查询,根据FIELD3的前5位,输出一个超过特定计数的列表。让我举一个具体的例子:

这就是我在DB中所做的:

FIELD1               FIELD2               FIELD3          
1234567314           333776543585218      333771434591151
1234567871           333771451776784      333771432365581
1234567314           333776543585218      333771240553976
1234567314           333776543585218      333773861003473
1234567314           333776543585218      333773861003473
1234567314           333776543585218      333023861003473
1234567314           333776543585218      333023861003473
1234567314           333776543585218      333023861003473
1234567337           333773660813075      333773650804767
1234567137           333773660798439      333771222628311
1234567319           333776543585219      333773660667594
1234567314           333776543585218      333901451463400
1234567314           333776543585218      333901451463400
现在,我想用以下方式在field1中输出数字:

OUTPUT FIELD1 (and related FIELD2 and FIELD3) who are exceeded a COUNT1 (EG: 3) based on FIELD3 having the same 5 first digits (33377)
OUTPUT FIELD1 (and related FIELD2 and FIELD3) who are exceeded a COUNT2 (EG: 10) based on FIELD3 NOT having the same 5 first digits (33377)
因此,在上面的示例中,我的输出将是:

1234567314           333776543585218      333771434591151
1234567314           333776543585218      333771240553976
1234567314           333776543585218      333773861003473
1234567314           333776543585218      333773861003473
1234567314           333776543585218      333023861003473
1234567314           333776543585218      333023861003473
1234567314           333776543585218      333023861003473
1234567314           333776543585218      333901451463400
1234567314           333776543585218      333901451463400
33377=4次,其他=5次。第一个阈值超过了计数,因此,报告所有行

基本上,上面报告的两个查询工作得非常完美,但我想将它们合并到一个查询中,以最大限度地减少查询时间并获得唯一的输出

非常感谢。
Lucas

要连接两个查询,请使用UNION:


正如在该页面中的示例中所示,您还可以使用附加列跟踪记录所属的选择。

若要加入两个查询,请使用UNION


在该页面的示例中,您还可以使用一个附加列来跟踪您的记录所属的选择。

您应该能够为此使用分析函数

SELECT field1, field2, field3
FROM (SELECT t.*,
             SUM(CASE WHEN field3 LIKE '33377%' THEN 1 ELSE 0 END) OVER (PARTITION BY field1) as cnthave,
             SUM(CASE WHEN field3 NOT LIKE '33377%' THEN 1 ELSE 0 END) OVER (PARTITION BY field1) as cntnothave
      FROM TABLE t
      WHERE timestamp between sysdate - interval '20' minute and sysdate - interval '2' minute
     ) t
WHERE (Other conditions here) AND
      (cnthave > 100 or cntnothave > 150);

您应该能够为此使用分析函数

SELECT field1, field2, field3
FROM (SELECT t.*,
             SUM(CASE WHEN field3 LIKE '33377%' THEN 1 ELSE 0 END) OVER (PARTITION BY field1) as cnthave,
             SUM(CASE WHEN field3 NOT LIKE '33377%' THEN 1 ELSE 0 END) OVER (PARTITION BY field1) as cntnothave
      FROM TABLE t
      WHERE timestamp between sysdate - interval '20' minute and sysdate - interval '2' minute
     ) t
WHERE (Other conditions here) AND
      (cnthave > 100 or cntnothave > 150);
使用UNION ALL:

SELECT  A.FIELD1,A.FIELD2,A.FIELD3
   FROM 
   TABLE A 
   INNER JOIN
   (
    SELECT FIELD1, COUNT(1) 
    FROM TABLE
    where SUBSTR(FIELD3,1,5)='33377' and
    timestamp between sysdate - interval '20' minute and sysdate - interval '2' minute
    GROUP BY FIELD1
    HAVING COUNT(1) >= 100
    ) B
    ON A.FIELD1 = B.FIELD1 where ...some other clauses who interacts with FIELD4,5,6,etc...
UNION ALL
SELECT  A.FIELD1,A.FIELD2,A.FIELD3
   FROM 
   TABLE A 
   INNER JOIN
   (
    SELECT FIELD1, COUNT(1) 
    FROM TABLE
    where SUBSTR(FIELD3,1,5)!='33377' and
    timestamp between sysdate - interval '20' minute and sysdate - interval '2' minute
    GROUP BY FIELD1
    HAVING COUNT(1) >= 150
    ) B
    ON A.FIELD1 = B.FIELD1 where ...some other clauses who interacts with FIELD4,5,6,etc... ;
在Oracle中,UNION很难确保结果集中没有重复项,这可能非常耗时。工会都避免了这个问题

分享和享受。

使用UNION ALL:

SELECT  A.FIELD1,A.FIELD2,A.FIELD3
   FROM 
   TABLE A 
   INNER JOIN
   (
    SELECT FIELD1, COUNT(1) 
    FROM TABLE
    where SUBSTR(FIELD3,1,5)='33377' and
    timestamp between sysdate - interval '20' minute and sysdate - interval '2' minute
    GROUP BY FIELD1
    HAVING COUNT(1) >= 100
    ) B
    ON A.FIELD1 = B.FIELD1 where ...some other clauses who interacts with FIELD4,5,6,etc...
UNION ALL
SELECT  A.FIELD1,A.FIELD2,A.FIELD3
   FROM 
   TABLE A 
   INNER JOIN
   (
    SELECT FIELD1, COUNT(1) 
    FROM TABLE
    where SUBSTR(FIELD3,1,5)!='33377' and
    timestamp between sysdate - interval '20' minute and sysdate - interval '2' minute
    GROUP BY FIELD1
    HAVING COUNT(1) >= 150
    ) B
    ON A.FIELD1 = B.FIELD1 where ...some other clauses who interacts with FIELD4,5,6,etc... ;
在Oracle中,UNION很难确保结果集中没有重复项,这可能非常耗时。工会都避免了这个问题


分享和享受。

将这两个查询结合起来很容易。不过有两个建议。首先,使用CTE而不是内联视图。它不会改变性能——只是看起来……更干净、更整洁(imho)。第二,如果要像这样组合两个查询,请添加一个字段,用于标识每一行及其存在的原因。使分析员的工作更容易一些

with
Tablecounts( Field1, Hits, Misses )As(
    Select  Field1,
            Sum( Case When Substr( Field3, 1, 5) = '33377' Then 1 Else 0 End ),
            Sum( Case When Substr( Field3, 1, 5) = '33377' Then 0 Else 1 End )
    From    Table
    Where   Timestamp Between Sysdate - Interval '20' Minute And Sysdate - Interval '2' Minute
    Group By Field1
)
Select  Rd.Field1, Rd.Field2, Rd.Field3,
        case when tc.Hits > 100
             then 'This is a hit'
             else 'This is a miss...or something' end as Why
From    Table     Rd
Join    Tablecounts Tc
    On  Tc.Field1 = Rd.Field1
    and( tc.Hits > 100 or tc.Misses > 150 );
编辑:我使用分析重写。除了风格上的细微差别外,它和戈登的一样。但戈登回答下的评论表明存在一个问题。在我看来,它应该会起作用。是否确实存在问题?如果是,是什么问题

with
Counts( Field1, Field2, Field3, Hits, Misses )As(
    Select  Field1, Field2, Field3,
            Sum( Case When Field3 Like '33377%' Then 1 Else 0 End ) Over( Partition By Field1 ),
            Sum( Case When Field3 Like '33377%' Then 0 Else 1 End ) Over( Partition By Field1 )
    From    Table
    Where   Timestamp Between Sysdate - Interval '20' Minute And Sysdate - Interval '2' Minute
)
Select  Field1, Field2, Field3,
        Case When Hits > 3
             Then 'This is a hit'
             else 'This is a miss...or something' end as Why
From    Counts
where   Hits > 100 or Misses > 150;

将这两个查询组合起来很容易。不过有两个建议。首先,使用CTE而不是内联视图。它不会改变性能——只是看起来……更干净、更整洁(imho)。第二,如果要像这样组合两个查询,请添加一个字段,用于标识每一行及其存在的原因。使分析员的工作更容易一些

with
Tablecounts( Field1, Hits, Misses )As(
    Select  Field1,
            Sum( Case When Substr( Field3, 1, 5) = '33377' Then 1 Else 0 End ),
            Sum( Case When Substr( Field3, 1, 5) = '33377' Then 0 Else 1 End )
    From    Table
    Where   Timestamp Between Sysdate - Interval '20' Minute And Sysdate - Interval '2' Minute
    Group By Field1
)
Select  Rd.Field1, Rd.Field2, Rd.Field3,
        case when tc.Hits > 100
             then 'This is a hit'
             else 'This is a miss...or something' end as Why
From    Table     Rd
Join    Tablecounts Tc
    On  Tc.Field1 = Rd.Field1
    and( tc.Hits > 100 or tc.Misses > 150 );
编辑:我使用分析重写。除了风格上的细微差别外,它和戈登的一样。但戈登回答下的评论表明存在一个问题。在我看来,它应该会起作用。是否确实存在问题?如果是,是什么问题

with
Counts( Field1, Field2, Field3, Hits, Misses )As(
    Select  Field1, Field2, Field3,
            Sum( Case When Field3 Like '33377%' Then 1 Else 0 End ) Over( Partition By Field1 ),
            Sum( Case When Field3 Like '33377%' Then 0 Else 1 End ) Over( Partition By Field1 )
    From    Table
    Where   Timestamp Between Sysdate - Interval '20' Minute And Sysdate - Interval '2' Minute
)
Select  Field1, Field2, Field3,
        Case When Hits > 3
             Then 'This is a hit'
             else 'This is a miss...or something' end as Why
From    Counts
where   Hits > 100 or Misses > 150;

UNION可能是一个可能的答案,但这是ORACLE,链接到MySQL,一个非常不同的野兽。谢谢,无论如何,现在我想我会使用Gordon建议的分析函数。UNION可能是一个可能的答案,但这是ORACLE,链接到MySQL,一个非常不同的野兽。谢谢,不管怎样,现在我想我将使用Gordon建议的分析函数。编辑:有趣的方法Gordon,不幸的是,查询的输出只会用一行(实际表的第一行)==>1234567401 | 33377523456789012 |33390123456789012@LucasRey . . . 我写了“分析函数”,然后就没用了。我的错。Gordon,你的查询速度很快(和我的相比),但很抱歉,我的输出有另一个问题。。。看来这个柜台不受尊重。在查询之后,我得到了一些field1的出现率低于100或150。它似乎有效,但不考虑计数器。请帮忙,我对你的查询速度非常满意!!!!这是输出的一部分(我使用bash脚本来计算出现的次数):1234567924=80 1234567424=62 1234567604=78 1234567857=101 1234567501=58 1234567034=97 1234567495=99 1234567980=63 1234567572=56 1234567716=78 1234567827=62 123456710=67 1234567814=74 1234567537=82 1234567360=91 1234567246=154@LucasRey . . . 也许你想要一个
而不是
(cnthave>100和cntnothave>150)
。原始查询相当于
。您只看到“另一个集合”上的值--“nothave”集合上的
cnthave
值,反之亦然。编辑:有趣的方法Gordon,不幸的是,查询的输出将只回复我一行(实表的第一行)==>1234567401 | 33377523456789012 |33390123456789012@LucasRey . . . 我写了“分析函数”,然后就没用了。我的错。Gordon,你的查询速度很快(和我的相比),但很抱歉,我的输出有另一个问题。。。看来这个柜台不受尊重。在查询之后,我得到了一些field1的出现率低于100或150。它似乎有效,但不考虑计数器。请帮忙,我对你的查询速度非常满意!!!!这是输出的一部分(我使用bash脚本来计算出现的次数):1234567924=80 1234567424=62 1234567604=78 1234567857=101 1234567501=58 1234567034=97 1234567495=99 1234567980=63 1234567572=56 1234567716=78 1234567827=62 123456710=67 1234567814=74 1234567537=82 1234567360=91 1234567246=154@LucasRey . . . 也许你想要一个
而不是
(cnthave>100和cntnothave>150)
。原始查询相当于
。你只是