Oracle SQL - 在where子句中实现MAX功能?

时间:2012-04-27 21:50:42

标签: sql oracle

两张桌子:

ItemComment(ItemId, ItemComment, DateCommentPosted)
Item (ItemId, ItemName, ItemPrice) 

我需要自去年6个月以来未收到任何评论的项目名称和价格。

我知道这不会奏效:

SELECT i.itemid, i.name, i.price 
  FROM Item i, ItemComment c
 WHERE i.itemid = c.itemid 
   AND Max(c.dateCommentPosted) < (add_months(SYSDATE,-6));

StackOverflow上有类似的答案,但Oracle并不喜欢它。任何特定于Oracle的事情?

4 个答案:

答案 0 :(得分:9)

使用首选的显式JOIN表示法以及GROUP BY和HAVING子句,您应该可以使用:

SELECT i.itemid, i.name, i.price 
  FROM Item i
  JOIN ItemComment c ON i.itemid = c.itemid
 GROUP BY i.itemid, i.name, i.price
HAVING MAX(c.dateCommentPosted) < (ADD_MONTHS(SYSDATE, -6));

您还可以使用WITH子句或直接在FROM列表中编写子查询,以计算为每个项目发布注释的最新日期,然后将其与Item表连接。

您可能想要考虑是否应该选择没有任何评论的项目。

  

如果我想显示/选择Max(c.dateCommentPosted)该怎么办?这是一个选择吗?如果我在select子句中添加它并在GROUP BY子句中添加dateCommentPosted,那会是正确的吗?

将它添加到select子句,但不是GROUP BY子句:

SELECT i.itemid, i.name, i.price, MAX(c.dateCommentPosted) AS dateCommentPosted
  FROM Item i
  JOIN ItemComment c ON i.itemid = c.itemid
 GROUP BY i.itemid, i.name, i.price
HAVING MAX(c.dateCommentPosted) < (ADD_MONTHS(SYSDATE, -6));

您可能更愿意退出AS。 AFAIK,Oracle绝对拒绝表别名中的AS(所以我把它留在那里),但它接受(但不要求)它在select-list中的'列别名'中。

顺便提一下,SQL标准,因此“所有”SQL DBMS,需要在HAVING子句中进行聚合比较,而HAVING子句需要GROUP BY子句。因此,GBH - Group By / Having以及严重的身体伤害。

答案 1 :(得分:3)

以下是另一种方法的示例:

with cte as (
  select i.itemid,
    max(DateCommentPosted) as LastCommentDate
  from Item i left join ItemComment c on c.itemid = i.itemid
  group by i.itemid
)
select i.itemid, i.ItemName, i.ItemPrice 
from Item i join cte c on c.itemid = i.itemid
where LastCommentDate is null or LastCommentDate < add_months(SYSDATE,-6)

在sqlfiddle here上查看此操作。您也可以通过这种方式轻松返回每个项目的最后评论日期。

答案 2 :(得分:2)

试试这个:

select i.itemid, i.name, i.price
  from Item i 
 where not exists (
     select 1
       from ItemComment c
      where c.dateCommentPosted between (SYSDATE - 180) and SYSDATE
        and c.itemid = i.itemid
 )

答案 3 :(得分:1)

也许它不是这个特定查询的最佳解决方案,但根据实际问题标题,您要查找的是HAVING语句,它允许您将聚合放入{{1} }子句

http://psoug.org/reference/group_by.html