Я работаю над футбольным сайтом, наряду со многими функциями, списками результатов. Таблицы разделяются между сезонами (название сезона и т.д.) И раундами (ведьмы генерируются каждый раз, когда начинается новый сезон, например, 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 различным раундам. Конечный результат должен быть списком каждого раунда, действующего в настоящее время в отношении каждого сезона.
Предположим, что следующие определения таблиц (без правильных индексов или ограничений)
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..., чтобы убедиться, что запрос не слишком неэффективен...
season_id
? Что у вас есть, и что вы хотите для окончательного результата?