0

嗨,我正在创建一个数据库,用于跟踪用户为我们的一种产品投票的次数。

有没有办法可以更改下面的查询以计算每年的最大票数?我正在使用 Oracle SQL 开发人员

创建表的结构为

Members(username, email, pwd) 
Votes (username*, prodCode*, score, voteDate)

笔记:

SELECT username, count(username)
FROM Votes NATURAL JOIN members
GROUP BY username, email
HAVING COUNT(*) >= All(SELECT count(username)
                   FROM Votes v1
                   GROUP BY username);
4

2 回答 2

4

我不完全确定我理解你的问题,但可能是这样的?

SELECT username, 
       extract(year from voteDate) as vote_year, 
       count(*) as votes_per_year,
       max(count(*)) over (partition by extract(year from voteDate)) as max_votes_per_year
FROM Votes vt
GROUP BY username, extract(year from voteDate);

这将为您提供每个用户和年份的计数以及每一行中每年的最大计数。(请注意,成员表不是必需的,因为您显然不需要其中的任何列)。

如果您需要在没有人投票(或某个特定用户未投票)的年份显示零计数,那么您将需要这样的东西:

with years as (
   select 2009 + level as year
   from dual
   connect by level <= 21
)  
SELECT username, 
       y.year, 
       count(vt.username) as votes_per_year,
       max(count(vt.username)) over (partition by y.year) as max_votes_per_year
FROM years y 
  LEFT JOIN Votes vt on y.year = extract(year from vt.voteDate)
GROUP BY username, y.year
order by y.year, username;

with ...这将使用公用表表达式 ( ) “即时”生成 2010 年到 2030 年之间的年份列表。您可以调整 CTE 以延长或缩小年数。

于 2013-06-03T07:59:28.787 回答
0

为此,您最好有一个带有年份的表格(或至少一个可以帮助您设置一组年份的数字表格)。

SELECT
    username
    , MAX(cnt) AS mcnt
FROM (
    SELECT
        username
        , count(username) AS cnt
    FROM members 
    CROSS JOIN Years
    INNER JOIN Votes ON (
        members.username = Votes.username -- using an INT here would be more efficient
        AND
        Votes.voteDate >= Years.firstJanuary
        AND
        Votes.voteDate < Years.firstJanuary+ 1 Year -- Pseudo code, you didn't mention any DBMS
    )
    GROUP BY username, prodCode, Years.firstJanuary
) AS X
于 2013-06-03T07:48:48.830 回答