帮助这个SQL查询

时间:2010-07-13 17:33:26

标签: sql oracle ora-00934

以下查询在第143列返回错误:“ORA-00934:此处不允许使用组功能”

SELECT * FROM 
TBLENTITYLOCATION TL INNER JOIN TBLENTITY TE ON TE.ENTITYID = TL.ENTITYID 
WHERE TE.ENTITYNAME = 'foobar' 
AND LOCATIONDATETIME = MAX(LOCATIONDATETIME)

如果我取出最后一行 - AND LOCATIONDATETIME = MAX(LOCATIONDATETIME),它会正常工作,但它会返回'foobar'的每个实例而不是最新的。有人能帮助我吗?

6 个答案:

答案 0 :(得分:7)

您不能在非聚合查询中使用聚合函数(max)。你想要的是这样的:

SELECT * 
FROM TBLENTITYLOCATION TL 
INNER JOIN TBLENTITY TE 
ON TE.ENTITYID = TL.ENTITYID 
WHERE TE.ENTITYNAME = 'foobar' 
AND LOCATIONDATETIME = (select MAX(LOCATIONDATETIME)
                        FROM TBLENTITYLOCATION TL 
                        INNER JOIN TBLENTITY TE 
                        ON TE.ENTITYID = TL.ENTITYID 
                        WHERE TE.ENTITYNAME = 'foobar')

基本规则是,如果您使用聚合函数(即min,max,avg等),则select语句中的所有列必须位于聚合函数或GROUP BY的一部分中条款。即使您拥有GROUP BY(在这种情况下不会执行您需要的操作),您的原始查询仍然无效,因为您无法在WHERE子句中引用聚合函数。要通过聚合函数进行筛选,您需要使用HAVING子句,该子句在聚合结果后应用(与之前评估的WHERE相反)。


或者,您可以使用ROWNUM和ORDER BY子句来实现相同的结果(基本上是Oracle的TOP版本):

select *
from (SELECT tl.*, te.*, rownum as rn 
      FROM TBLENTITYLOCATION TL 
      INNER JOIN TBLENTITY TE 
      ON TE.ENTITYID = TL.ENTITYID 
      WHERE TE.ENTITYNAME = 'foobar'
      ORDER BY LOCATIONDATETIME DESC)
where rn = 1

看起来你可能会把它折叠成一个选择,但这是一种错觉。如果您这样做,ROWNUM标准将在ORDER BY之前应用,因此您将得到一个半随机行。

我相信第一个版本会更有效率,因为它不需要对结果进行排序。

答案 1 :(得分:4)

或者,您可以在WHERE子句中使用子查询,如下所示:

SELECT * FROM 
TBLENTITYLOCATION TL INNER JOIN TBLENTITY TE ON TE.ENTITYID = TL.ENTITYID 
WHERE TE.ENTITYNAME = 'foobar' 
AND LOCATIONDATETIME = (SELECT MAX(LOCATIONDATETIME) FROM TBLENTITYLOCATION)

答案 2 :(得分:3)

你可以尝试:

SELECT Top(1) * FROM  
TBLENTITYLOCATION TL INNER JOIN TBLENTITY TE ON TE.ENTITYID = TL.ENTITYID  
WHERE TE.ENTITYNAME = 'foobar'  
ORDER BY LOCATIONDATETIME DESC

答案 3 :(得分:0)

从where子句中取出MAX(LOCATIONDATETIME)并将其放在select子句中:

SELECT MAX(LOCATIONDATETIME)FROM TBLENTITYLOCATION TL INNER JOIN TBLENTITY TE ON TE.ENTITYID = TL.ENTITYID WHERE TE.ENTITYNAME ='foobar'

还要在select子句中添加其他字段,因为选择*是不好的做法

答案 4 :(得分:0)

在Select语句中使用MAX

SELECT *,MAX(LOCATIONDATETIME)FROM TBLENTITYLOCATION TL INNER JOIN TBLENTITY TE ON TE.ENTITYID = TL.ENTITYID WHERE TE.ENTITYNAME ='foobar'

答案 5 :(得分:0)

您可以对Query降序排序,然后只使用第一行。