如何在子查询结果上使用MAX()?

时间:2013-04-24 03:08:10

标签: sql oracle subquery aggregate-functions max

我是Oracle和SQL世界的新手。对于我的生活中我无法弄清楚的查询有一个小问题,我花了几个小时尝试不同的方法,我无法得到我期望的结果。所以继承我的问题:

SELECT *
from(Select membership.mem_desc,membership.mem_max_rentals,membership_history.mem_type,      
    count(membership_history.MEM_TYPE) as membership_count
    from membership_history
    JOIN membership ON membership.mem_type = membership_history.mem_type
    group by (membership_history.mem_type,membership.mem_desc,membership.mem_max_rentals)
    ) g
WHERE g.membership_count = (select MAX(membership_count) from g); 

因此内部查询完美运行并返回两个结果。现在我有这两个值,我试图弄清楚如何返回具有membership_count最大值的行,这是我一直卡住的地方。在上面的查询中,我尝试在where子句中使用MAX()但在select中我不断得到错误'table not found'(意思是'g')。所以我的问题是如何在子查询的结果上使用MAX()函数?任何想法或建议将不胜感激!!!!!

7 个答案:

答案 0 :(得分:12)

您不需要找到最大值的子查询 相反,;在订购行之后,您只需要第一个行:

select * from (
  select 
    membership.mem_desc,
    membership.mem_max_rentals,
    membership_history.mem_type,      
    count(membership_history.MEM_TYPE) as membership_count
  from membership_history
  JOIN membership ON membership.mem_type = membership_history.mem_type
  group by (membership_history.mem_type,membership.mem_desc,membership.mem_max_rentals)
  ORDER BY 4 DESC  -- Added this line
) g
WHERE ROWNUM = 1. -- Added this line

答案 1 :(得分:4)

这都是不错的SQL。

使用max主键列值查找列值的最佳方法是:

SELECT .... from tablename
WHERE ... AND
  (SELECT max(primary key name) FROM tablename WHERE .... ) = primary_key_name

此示例将返回标量值。

答案 2 :(得分:1)

我在访问查询中遇到了类似的问题...根据此主题中的一些注释,我们是否应该理解ACCESS MAX功能只能用于主键字段? ...基本上,我有一个表定义与实体有关的地址,但有一点点扭曲; 1)一旦保存,不允许删除或更改记录(意味着实体可以有多个地址记录),2)任何当前的实体地址可以具有; HOME(1记录)或HOME和MAIL(2条记录)...每条地址记录都有一个(ID)(自动编号主键)与HOME记录(ID)匹配的HOME ID(HID)(HID不是主键和并不是唯一的)和实体ID(EID)......所以...当我尝试使用子查询来获取给定实体的最大(HID)值时,我只想要返回当前地址...我在子查询中使用MAX发现的是它无法运行,因为ACCESS错误地认为它有太多的子查询匹配记录......或者......它错误地返回它不应该返回的行。

我找到解决此问题的唯一方法是使用Max Function替换max子查询,Max Function返回实体的MAX HID值(该函数在VBA中使用带有DAO逻辑的子查询语句)< / p>

这是HOME子查询,它是主Query的一部分(主查询需要为每个实体返回一行; EID,Home.Address,Mail.Address)

Select *
From tbAddresses As tba1
Where tba1.aType = "Home"
  And tba1.HID = (Select MAX(tba2.HID) 
                      From tbAddresses As tba2 
                     Where tba1.EID = tba2.EID)

主要查询仅在Home和Mail(未显示)的Where子句被下面的函数替换时才能正常工作。如果如上所述包含MAX子查询,则它不起作用。

因此,如果MAX函数需要PRIMARY KEY字段才能工作,这可能解释了为什么我的查询失败,尽管这听起来像是一个主要限制。

Where tba1.HID = fnGetMaxHID(tba1.EID) 

这是一些应该只返回3行的测试数据

ID    HID    EID   aType  Address
 1      1    100   Home   Blah 1
 2      2    101   Home   Blah 2
 3      2    101   Mail   PO Box Blah 0
 4      4    102   Home   Blah 3
 5      5    101   Home   Blah 4

最后一点,Access Pro的几个版本; 2002年,2003年,2016年进行了测试,所有产生了相同的结果。所以这个问题要么是max函数的固有怪癖,要么是某种可能被忽略或被忽视的bug? ...该函数对我来说是一种解决方法,但可能对其他函数不起作用,所以如果澄清MAX函数会很好。

答案 3 :(得分:0)

您可以尝试类似

的内容
 SELECT membership.mem_desc,membership.mem_max_rentals,membership_history.mem_type, membership_count, rank() over ORDER BY membership_count DESC as ranky
from
(Select membership.mem_desc,membership.mem_max_rentals,membership_history.mem_type,      
count(membership_history.MEM_TYPE) as membership_count
from membership_history
JOIN membership ON membership.mem_type = membership_history.mem_type
group by (membership_history.mem_type,membership.mem_desc,membership.mem_max_rentals)
) 
WHERE ranky =1;

答案 4 :(得分:0)

您不能直接在where子句中使用派生表,它会给出table or view does not exist错误 为了获得最大计数值,您可以使用HAVING子句或Analytical FunctionsRownum

select * from
      (Select membership.mem_desc,membership.mem_max_rentals,membership_history.mem_type,      
      count(membership_history.MEM_TYPE) as membership_count
      from membership_history a
      JOIN membership b ON b.mem_type = a.mem_type
      group by (membership_history.mem_type,membership.mem_desc,membership.mem_max_rentals)
      having count(a.MEM_TYPE) = (Select      
      MAX(count(a.MEM_TYPE)) from membership_history a
      JOIN membership b ON b.mem_type = a.mem_type
      group by (a.mem_type,b.mem_desc,b.mem_max_rentals)));

(OR)

select * from
(SELECT g.*,rank() over (order by membership_count desc) rnk from
      (Select membership.mem_desc,membership.mem_max_rentals,membership_history.mem_type,      
      count(membership_history.MEM_TYPE) as membership_count
      from membership_history
      JOIN membership ON membership.mem_type = membership_history.mem_type
      group by (membership_history.mem_type,membership.mem_desc,membership.mem_max_rentals)) g)
WHERE rnk=1;

(OR)

select * from
(SELECT g.*,rownum rn from
      (Select membership.mem_desc,membership.mem_max_rentals,membership_history.mem_type,      
      count(membership_history.MEM_TYPE) as membership_count
      from membership_history
      JOIN membership ON membership.mem_type = membership_history.mem_type
      group by (membership_history.mem_type,membership.mem_desc,membership.mem_max_rentals)
      order by membership_count desc) g)
WHERE rn=1;

答案 5 :(得分:0)

我认为最干净的解决方案是使用ALL比较条件。它用于将值与列表或子查询进行比较。

SELECT 
  m.mem_desc,
  m.mem_max_rentals,
  mh.mem_type,      
  COUNT(mh.mem_type) as membership_count
FROM membership_history mh
JOIN membership m ON m.mem_type = mh.mem_type
GROUP BY mh.mem_type,m.mem_desc,m.mem_max_rentals
HAVING membership_count >= ALL (
  SELECT count(*)
  FROM membership_history
  GROUP BY mem_type
)   

答案 6 :(得分:0)

在这里,聚合可能不会出现在WHERE子句中,除非它在HAVING子句或选择列表中包含的子查询中,并且正在聚合的列是SQL Server中的外部引用。

为进行演示,我们有一个名为“ Info”的表,其中包含一些记录。

--Select records from info
SELECT * FROM INFO

ScreenShot

enter image description here

问题陈述:查找有关最大ID的INFO的所有详细信息。

SELECT * FROM INFO WHERE ID = MAX(ID)

他执行上述脚本时,出现以下错误:

消息147,级别15,状态1,第3行
除非聚合不在HAVING子句或选择列表中包含的子查询中,并且聚合的列是外部引用,否则聚合可能不会出现在WHERE子句中。

即使解决方案是在查询描述本身中给出的,他也无法解决此问题。

由于经验不足,他根据错误消息提出了上述查询的另一个版本。

SELECT * FROM INFO HAVING ID = MAX(ID)

消息8121,第16级,状态1,第1行
列'INFO.id'在HAVING子句中无效,因为它既不在聚合函数中也不在GROUP BY子句中。

他实际上想要的是ID的表INFO最大值。根据问题陈述,正确的解决方案如下,不会产生错误。

SELECT * FROM INFO WHERE ID = (SELECT MAX(ID) FROM INFO)

ScreenShot

enter image description here