MySQL - 在查询时转换和比较日期

时间:2009-12-10 06:31:34

标签: php mysql date

我正在研究一个足球网站女巫,以及许多功能,列出结果表。表格在季节(季节名称等)和轮次之间分开(每当新赛季开始时都会生成女巫,如2008/2009,2009 / 2010等)

圆桌有一个开始日期和一个结束日期,我必须在网站前端使用的唯一方法是将这些日期与同一季节的剩余轮次进行比较。

所有数据都是从xml中获取的,日期如下所示:

2009-08-16

所以,我的两个问题:

  • 比较日期(并且可能会即时转换它们)并发现女性圆形的结束日期最长;
  • 得到正确的回合(未来几轮可能已经在数据库中,但如果您知道我的意思,那么当前回合可能是另一回合之前)

我不是专家或任何有SQL的东西,所以我想知道你们会怎么做。

这是我当前的查询:

SELECT seasons.competition_id AS cid, 
       seasons.id AS sid, 
       rounds.id AS rid, 
       seasons.start_date AS sstart, 
       seasons.end_date AS send, 
       rounds.start_date AS rstart, 
       rounds.end_date AS rend, 
       round_groups.id AS rgid 
  FROM seasons 
INNER JOIN rounds ON seasons.id=rounds.season_id 
LEFT JOIN round_groups ON rounds.id=round_groups.round_id

ps:你可能会注意到我忘记提及的round_groups表,它是在某个赛季被分组时使用的,比如欧足联和冠军。

编辑:

季节是数据库中的一个条目,每个季节更新一次,因为一些比赛改变了他们对本赛季赞助商的名称。该轮次至少每季更换一次,但可能会有更多变化。在像UEFA这样的某些比赛中,他们有一些首轮淘汰赛,然后是小组赛阶段,然后再次淘汰,这将导致3轮不同。最终输出应该是每个赛季当前活跃的每一轮的列表。

1 个答案:

答案 0 :(得分:2)

让我们假设以下表定义(没有适当的索引或约束)

CREATE TABLE seasons (
  id int auto_increment,  
  competition_id int,  
  start_date DATE,  
  end_date DATE, 
  description varchar(32),
  primary key(id)
)

CREATE TABLE rounds (
  id int auto_increment,  
  season_id int,  
  start_date DATE,  
  end_date DATE,    
  description varchar(32),
  primary key(id)
)

以及一些示例数据

INSERT INTO seasons (competition_id,start_date,end_date,description) VALUES
  (1, '2007-3-15', '2007-9-15', 'FooCup 2007'),  
  (1, '2008-3-7', '2007-9-21', 'FooCup 2008'),  
  (1, '2009-4-1', '2007-9-21', 'FooCup 2009'),    
  (2, '2009-1-1', '2009-12-20', 'xyz 2009') 

INSERT INTO rounds (season_id, start_date, end_date, description) VALUES
  (1, '2007-3-15', '2007-4-15', 'foo 2007 1'),
  (1, '2007-4-16', '2007-8-15', 'foo 2007 2'),
  (1, '2007-8-16', '2007-9-15', 'foo 2007 3'),  
  (2, '2008-3-7', '2008-4-21', 'foo 2008 1'),
  (2, '2008-4-21', '2008-8-16', 'foo 2008 2'),
  (2, '2008-8-17', '2008-9-21', 'foo 2008 3'),
  (3, '2009-4-1', '2009-5-1', 'foo 2009 1'),
  (3, '2009-5-2', '2009-8-1', 'foo 2009 2'),
  (3, '2009-8-2', '2009-9-21', 'foo 2009 3'),
  (4, '2009-1-1', '2009-12-20', 'xyz ')

你是一个修复时间/日期(fd),并希望在start_date和end_date之间有这个fd的记录。 BETWEEN ... AND ...完全测试并使用日期/时间值。 E.g。

SELECT
  id, description 
FROM
  round as r
WHERE
  '2008-6-17' BETWEEN  r.start_date AND r.end_date

返回当时所有回合(适用于所有比赛)的记录 现在你在season_id上用season表加入吧。并将结果限制为某个competition_id(如果您愿意)。

SELECT
  r.description as rd, r.start_date, r.end_date    
FROM
  rounds as r  
JOIN
  seasons as s  
ON
  r.season_id=s.id
WHERE
  '2009-6-17' BETWEEN  r.start_date AND r.end_date  
  AND s.competition_id=1

编辑:对不起,误读了这个问题.... 假设你知道competition_id并且有一个修复日期(2009-08-16),你可以通过

获得season.id
SELECT
  s.id  
FROM
  seasons as s  
WHERE
  s.competition_id=1
  AND '2009-08-16' BETWEEN s.start_date AND s.end_date

现在你可以加入season.id = rounds.season_id来获得本赛季的所有回合。

SELECT
  r.id  
FROM
  seasons as s  
JOIN
  rounds as r  
ON
  s.id=r.season_id
WHERE
  s.competition_id=1
  AND '2009-08-16' BETWEEN s.start_date AND s.end_date

(轮次:在这种情况下为7,8,9) 将结果限制为最高round.id的最简单选项是让MySQL按降序顺序舍入rounds.id,并将结果限制为一条记录。

SELECT
  r.id  
FROM
  seasons as s  
JOIN
  rounds as r  
ON
  s.id=r.season_id
WHERE
  s.competition_id=1
  AND '2009-08-16' BETWEEN s.start_date AND s.end_date
ORDER BY
  r.id DESC
LIMIT
  1

使用EXPLAIN SELECT ...确保查询 效率低......