18

我是 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); 

所以内部查询完美运行并返回两个结果。现在我有了这两个值,我试图弄清楚如何返回具有最大成员计数的行,这是我一直卡住的地方。在上面的查询中,我尝试在 where 子句中使用 MAX(),但在该选择中,我不断收到错误“找不到表”(意思是“g”)。所以我的问题是如何对子查询的结果使用 MAX() 函数?任何想法或建议将不胜感激!!!!!!

4

7 回答 7

14

您不需要找到最大值的子查询。
反而, ; 在对行进行排序后, 您只需要第一行:

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
于 2013-04-24T05:07:07.450 回答
4

这都是很好的 SQL。

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

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

此示例将返回一个标量值。

于 2014-04-19T16:48:14.520 回答
1

我在 Access Query 中遇到了类似的问题……根据这个线程中的一些评论,我们是否理解 ACCESS MAX 函数只能用于/与主键字段一起使用?...基本上,我有一个表,其中定义了与实体相关的地址,但是略有不同;1)一旦保存,就不允许删除或更改记录(意味着一个实体可以有多个地址记录),2)任何当前实体地址都可以有;HOME(1 条记录)或 HOME 和 MAIL(2 条记录)......每个地址记录都有一个(ID)(自动编号主键)一个与 HOME 记录的(ID)匹配的 HOME ID(HID)(HID 不是主键和不是唯一的)和一个实体 ID(EID)......所以......当我尝试使用子查询来获取给定实体的最大(HID)值时,我只希望返回当前地址......

我发现解决此问题的唯一方法是将最大子查询替换为返回实体的 MAX HID 值的 Max 函数(该函数在 VBA 中使用带有 DAO 逻辑的子查询语句)

这是 HOME 子查询,它是主查询的一部分(主查询需要为每个实体返回一行;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 函数的固有怪癖,要么是某种可能被忽略或被忽视的错误?...该功能对我来说是一种解决方法,但可能对其他人不起作用,所以如果澄清 MAX 功能会很好。

于 2018-04-15T23:52:02.663 回答
1

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

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

--Select records from info
SELECT * FROM INFO

截屏

在此处输入图像描述

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

SELECT * FROM INFO WHERE ID = MAX(ID)

当他执行上述脚本时,它给了他以下错误:

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

即使在查询描述中给出了解决方案,他也无法解决这个问题。

由于缺乏经验,他根据错误信息想出了上述查询的另一个版本。

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)

截屏

在此处输入图像描述

于 2020-05-23T08:04:33.153 回答
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)));

(或者)

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;

(或者)

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;
于 2013-04-24T06:15:04.253 回答
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;
于 2013-04-24T03:26:44.347 回答
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
)   
于 2015-06-21T05:12:55.860 回答