MySQL - конвертировать и сравнивать даты по запросу

0

Я работаю над футбольным сайтом, наряду со многими функциями, списками результатов. Таблицы разделяются между сезонами (название сезона и т.д.) И раундами (ведьмы генерируются каждый раз, когда начинается новый сезон, например, 2008/2009, 2009/2010 и т.д.)

В таблице раундов

есть дата начала и дата окончания, и единственный способ, которым я должен динамически знать, что я должен работать с интерфейсом веб-сайта, - это сравнить эти даты с оставшимися раундами относительно того же сезона.

Все данные извлекаются из xml, а даты выглядят следующим образом:

2009-08-16

Итак, мои 2 проблемы:

  • сравнить даты (и, возможно, конвертировать их на лету) и узнать, что колдун имеет самую большую дату окончания;
  • получите правильный раунд (некоторые будущие раунды могут быть уже в базе данных, но текущий раунд может быть другим до тех пор, если вы знаете, что я имею в виду)

Я не эксперт или что-то еще с 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, о которой я забыл упомянуть, она использовалась, когда определенный сезон делится на группы, такие как УЕФА и чемпионы.

ИЗМЕНИТЬ:

Сезон - это запись в базе данных, которая обновляется один раз за сезон, потому что некоторые соревнования меняют свое имя относительно спонсора сезона. Круглый меняется как минимум раз в сезон, но может иметь больше изменений. В некоторых соревнованиях, таких как УЕФА, у них есть несколько первых раундов ликвидации, затем групповой этап, а затем снова элиминация, что приведет к 3 различным раундам. Конечный результат должен быть списком каждого раунда, действующего в настоящее время в отношении каждого сезона.

  • 0
    Я не понимаю - много говорят о датах и турах, но пример включается в season_id ? Что у вас есть, и что вы хотите для окончательного результата?
  • 0
    Сезон - это запись в базе данных, которая обновляется один раз за сезон, потому что некоторые соревнования меняют свое имя относительно спонсора сезона. Раунд меняется как минимум раз в сезон, но может иметь больше изменений. В некоторых соревнованиях, таких как УЕФА, у них есть несколько первых отборочных раундов, затем групповой этап, а затем повторный отбор, в результате которого будет 3 разных раунда. Окончательным результатом должен быть список каждого раунда, который в настоящее время активен в отношении каждого сезона.
Показать ещё 2 комментария
Теги:
date

1 ответ

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) и хотите, чтобы записи имели этот fd между start_date и end_date. BETWEEN... AND... точно тестирует это и работает со значениями даты/времени. Например.

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

возвращение записей для всех раундов (для всех соревнований) в это время.
Теперь вы присоединитесь к этому сезону с сезоном. И ограничьте результаты определенным критерием конкуренции (если хотите).

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

Изменить: извините, неправильно прочитайте вопрос.... Предполагая, что вы знаете compet_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

Теперь вы можете ПРИСОЕДИНЯТЬСЯ к сезону .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

(раунды: id 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..., чтобы убедиться, что запрос не слишком неэффективен...

  • 0
    Спасибо, это напомнило мне, что поля даты в моих таблицах - это VARCHAR, а не дата, и поэтому мне, вероятно, потребуется преобразовать их перед сравнением. В любом случае, это помогло, но мне все еще нужно знать, как получить последний раунд в случае, если он не совпадает.
  • 0
    Еще раз спасибо, это не полностью соответствовало моим потребностям, но дало мне свет для решения, так что я принимаю ваш ответ. Ура!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню