查找最新或最早的日期

时间:2016-03-18 23:01:18

标签: sql oracle

我有一个名为team_ID的外键表,一个名为game_date的日期列,以及一个名为result的char列。我需要找到下一场排球比赛的时间。我已成功将比赛日期缩小到所有尚未发生的排球比赛,因为结果为IS NULL。我有所有的选择,我只需要找到最早的日期。

以下是我所得到的:

SELECT game.game_date, team.team_name
FROM game
JOIN team
ON team.team_id = game.team_id
WHERE team.sport_id IN
    (SELECT sport.sport_id
    FROM sport
    WHERE UPPER(sport.sport_type_code) IN
        (SELECT UPPER(sport_type.sport_type_code)
        FROM sport_type
        WHERE UPPER(sport_type_name) like UPPER('%VOLLEYBALL%')
        )
    )
AND game.result IS NULL;

我是时间旅行者,所以不要介意旧约会。

当我运行它时,我明白了:

GAME_DATE   TEAM_NAME
----------- ----------
11-NOV-1998 BEars
13-NOV-1998 BEars
13-NOV-1998 WildCats
14-NOV-1998 BEars

如何进行设置,以便 MIN(DATE)TEAM_NAME在该日播放?

我已尝试AND game.game_date = MIN(game.game_date),但它只是告诉我这里不允许使用群组功能。必须有一种方法来检索MIN(game_date)并将其用作要满足的条件。

我使用的是Oracle 11g pl / sql。

Game ERD

这应该是最终的工作代码。

SELECT *
  FROM 
    (
    SELECT g.game_date, t.team_name
      FROM game g
      JOIN team t
        ON t.team_id = g.team_id
      JOIN sport s
        ON t.sport_id = s.sport_id
      JOIN sport_type st
        ON UPPER(s.sport_type_code) IN UPPER(st.sport_type_code)
     WHERE UPPER(sport_type_name) like UPPER('%VOLLEYBALL%')
       AND g.result IS NULL
  ORDER BY g.game_date
    )
WHERE ROWNUM = 1;

3 个答案:

答案 0 :(得分:3)

在将ROWNUM子句应用于查询之前生成ORDER BY伪列。如果您只是执行WHERE ROWNUM <= X,那么您将按照Oracle从数据文件生成数据的顺序获得X行,而不是X最小行。为了保证获得最小行,您需要先使用ORDER BY,然后按照ROWNUM进行过滤:

SELECT *
FROM   (
  SELECT g.game_date, t.team_name
  FROM   game g
         JOIN team t
         ON t.team_id = g.team_id
         INNER JOIN sport s
         ON t.sport_id = s.sport_id
         INNER JOIN sport_type y
         ON UPPER( s.sport_type_code ) = UPPER( y.sport_type_code )
  WHERE  UPPER( y.sport_type_name) LIKE UPPER('%VOLLEYBALL%')
  AND    g.result IS NULL
  ORDER BY game_date ASC -- You need to do the ORDER BY in an inner query
)
WHERE ROWNUM = 1; -- Then filter on ROWNUM in an outer query.

如果要返回具有最小日期的多行,请执行以下操作:

SELECT game_date,
       team_name
FROM   (
  SELECT g.game_date,
         t.team_name,
         RANK() OVER ( ORDER BY g.game_date ASC ) AS rnk
  FROM   game g
         JOIN team t
         ON t.team_id = g.team_id
         INNER JOIN sport s
         ON t.sport_id = s.sport_id
         INNER JOIN sport_type y
         ON UPPER( s.sport_type_code ) = UPPER( y.sport_type_code )
  WHERE  UPPER( y.sport_type_name) LIKE UPPER('%VOLLEYBALL%')
  AND    g.result IS NULL
)
WHERE rnk = 1;

答案 1 :(得分:0)

你可以简单地按日期和SELECT TOP 1订购吗?我认为这是Oracle中的语法:

WHERE ROWNUM&lt; = number;

答案 2 :(得分:0)

select game.game_date,team.team_name from (
SELECT game.game_date, team.team_name, rank() over (partition by team.team_name order by game.game_date asc) T
FROM game
JOIN team
ON team.team_id = game.team_id
WHERE team.sport_id IN
    (SELECT sport.sport_id
    FROM sport
    WHERE UPPER(sport.sport_type_code) IN
        (SELECT UPPER(sport_type.sport_type_code)
        FROM sport_type
        WHERE UPPER(sport_type_name) like UPPER('%VOLLEYBALL%')
        )
    )
AND game.result IS NULL 
) query1 where query1.T=1;