两张桌子:
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的事情?
答案 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} }子句