为什么这些查询不相同? (相关子查询与组相关)

时间:2014-12-23 21:39:53

标签: sql sql-server

为什么这两个SQL查询不相同?一个使用相关子查询,另一个使用group by。第一个从我的数据库产生超过51000行,第二个接近66000行。在这两种情况下,我只是试图返回所有符合规定条件的部分,仅限当前版本。输出文件的比较显示方法#1(oracle_test1.txt)无法返回相当多的值。基于此,我只能假设方法#2是正确的。我有一些代码已经使用了方法#1很长一段时间,但似乎我将不得不改变它。关于相关子查询的我的推理是,当内部选择比较自连接中的列时,它将找到所有匹配的prev值的最大值;然后返回最大prev值以在外部查询中使用。我在很久以前就熟悉了group by的使用之前设计了那个查询。任何见解将不胜感激。

查询#1

select pobj_name, prev 
from pfmc_part 
where pmodel in ('PN-DWG', 'NO-DWG') and pstatus = 'RELEASED' 
and prev = (select max(prev) from pfmc_part a where a.pobj_name = pfmc_part.pobj_name) 
order by pobj_name, prev" 

查询#2

select pobj_name, max(prev) prev 
from pfmc_part 
where pmodel in ('PN-DWG', 'NO-DWG') and pstatus = 'RELEASED' 
group by pobj_name 
order by pobj_name, prev"

示例输出:

Query #2            Query #1
P538512 B   P538512 B
P538513 A   P538513 A
P538514 C   P538514 C
P538520 B
P538522 B   P538522 B
P538525 A   P538525 A
P538531 C   P538531 C
P538533 A   P538533 A
P538538 B
P538541 B
P538542 B
P538553 A   P538553 A
P538569 A   P538569 A

5 个答案:

答案 0 :(得分:1)

查询1返回每个最大ID,然后返回那些具有在where子句中指定类型的pmodel的最大ID。

而查询2正在选择所有项目,其中包含在where子句中指定类型的pmodel以及每个项目的最大ID。

您可能拥有的数据不是满足查询2中where子句的max id,这就是在查询1中省略它的原因

答案 1 :(得分:1)

有两个不同之处,其余的答案都集中在一个上。 " easy"不同之处在于max()中的group by受过滤子句的影响。另一个查询中的max()没有过滤器,因此它可能不返回任何行(当max(prev)在行上时,否则会被where条件过滤掉。

此外,如果给定where的多行具有相同的max(prev)值,则pobj_name版本的查询可能会返回重复的行。 group by永远不会返回重复的行。

答案 2 :(得分:0)

此查询

select pobj_name, prev 
from pfmc_part 
where pmodel in ('PN-DWG', 'NO-DWG') and pstatus = 'RELEASED' 
and prev = (select max(prev) from pfmc_part a where a.pobj_name = pfmc_part.pobj_name) 
order by pobj_name, prev" 

有一个where子句声明,导致它返回更少的行 - 特别是只有prev =(子查询)的行。 and prev使其完全不同,并将值分配到第一行的prev

如果你想要它们更相似,你需要像这样修改它

select pobj_name, prev, maxes.max
from pfmc_part 
JOIN (select max(prev) as max from pfmc_part a where a.pobj_name = pfmc_part.pobj_name) maxes
where pmodel in ('PN-DWG', 'NO-DWG') and pstatus = 'RELEASED' 
order by pobj_name, prev" 

答案 3 :(得分:0)

在查询1中,您只选择prev字段等于max(prev)的行,而在查询2中,您选择的所有记录ALONG WITH max(prev)满足where和where中的条件group by子句。

基本上,查询1和查询2具有完全不同的where子句。希望这能解释查询1中缺少的记录。

答案 4 :(得分:0)

您的查询#1肯定无法返回给定pobj_name的行,其中该名称的最大prev与当前数据库中的修订不对应。如果跳过修订版或删除了其行,则可能会发生这种情况。

您的查询#2不会受到查询#1的限制,并且由于避免了相关的子查询,它可能会表现得更好。但是,如果您想要的数据不仅仅是pobj_name而且需要聚合各组的功能,那将是不合适的。顺便说一句,在prev子句中包含ORDER BY是没有意义的,因为pobj_name对于每个结果行已经是唯一的。

总的来说,如果两个查询碰巧返回类似的结果,那么这是数据细节的问题,而不是查询。他们完全不同地得出结果。