4

两张表:

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

4 回答 4

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 子句中添加它并dateCommentPosted在 GROUP BY 子句中添加,那是否正确?

将其添加到 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(所以我把它留在那里),但它在选择列表的“列别名”中接受(但不需要)它。

Incidentally, the SQL Standard, and therefore 'all' SQL DBMS, require aggregate comparisons in the HAVING clause, and the HAVING clause requires a GROUP BY clause. Hence, GBH — Group By / Having as well as Grievous Bodily Harm.

于 2012-04-27T23:07:29.463 回答
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 的实际操作。您还可以通过这种方式轻松返回每个项目的最后评论日期。

于 2012-04-27T22:21:13.620 回答
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
 )
于 2012-04-27T21:57:00.973 回答
1

也许它不是此特定查询的最佳解决方案,但根据实际问题标题,您正在寻找的是HAVING语句,它允许您将聚合放入WHERE子句

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

于 2012-04-27T21:57:53.727 回答