有人可以帮我加入2个查询吗? 基本上它是具有不同子句的相同查询(请注意FIELD3过滤器和子查询中的相关计数器):
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... ;
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 DB,对于这个查询,只需要3个字段,如下所示。 我正在尝试使用多个计数进行查询。我需要的是一个查询,根据FIELD3的前5位数输出超过特定计数的列表。让我举一个具体的例子:
这就是我对数据库的看法:
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次出现。第一个阈值超过了计数,因此报告所有行。
基本上,上面报告的2个查询工作完美,但我想将它们合并为一个,以最大限度地缩短查询时间并获得独特的输出。
非常感谢。 卢卡斯
答案 0 :(得分:3)
您应该可以使用分析函数。
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);
答案 1 :(得分:2)
要加入两个查询,请使用 UNION :https://docs.oracle.com/cd/E17952_01/refman-5.1-en/union.html
在您可以在该页面中找到的示例中,您还可以使用其他列来跟踪您的记录所属的选择。
答案 2 :(得分:0)
使用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避免了这个问题。
分享并享受。
答案 3 :(得分:0)
组合这两个查询很简单。但有两点建议。首先,使用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;