2009-12-10 6 views
0

Je travaille sur un site de football, avec de nombreuses fonctionnalités, des listes de résultats. Les tables sont séparées entre les saisons (nom de la saison, etc.) et les rondes (qui sont générées chaque fois qu'une nouvelle saison démarre, comme 2008/2009, 2009/2010, etc.)MySQL - convertir et comparer les dates sur la requête

table ronde a une date de début et une date de fin , et la seule façon dont je dois dinamically savoir avec lequel je devrais travailler dans le frontend de site Web est en comparant ces dates avec les tours restants concernant la même saison.

Toutes les données sont extraites d'un xml, et les dates ressembler à ceci:

2009-08-16 

Alors, mes 2 problèmes:

  • Comparer les dates (et les convertir probablement on-the voler) et découvrir sorcière ronde a la plus grande date de fin;
  • obtenir le tour droit (quelques tours à venir peut-être déjà dans la base de données, mais le cycle actuel pourrait être une autre avant ceux-ci, si vous savez ce que je veux dire)

Je ne suis pas expert ou quoi que ce soit avec SQL , donc j'aimerais savoir comment vous feriez ça.

Voilà ma question actuelle:

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: vous pouvez remarquer la table round_groups que j'oublié de mentionner, il est utilisé quand une certaine saison est divisée en groupes, comme l'UEFA et Champions.

EDIT:

Une saison est une entrée sur la base de données est mise à jour une fois par saison, parce que certaines compétitions changent leur nom en ce qui concerne le commanditaire de la saison. Le tour change une fois par saison au moins, mais peut avoir plus de changements. Dans certaines compétitions comme l'UEFA, ils disputent des premiers tours éliminatoires, puis une phase de groupe, puis une élimination à nouveau, ce qui se traduirait par 3 tours différents. Le résultat final devrait être une liste de tous les tours actuellement actifs pour chaque saison.

+0

Je ne comprends pas - il y a beaucoup de discussions sur les dates et tournées, mais l'exemple joint sur la 'season_id'? Qu'avez-vous, et que voulez-vous pour la sortie finale? –

+0

Une saison est une entrée de la base de données qui est mise à jour une fois par saison, car certaines compétitions changent de nom pour le sponsor de la saison. Le tour change une fois par saison au moins, mais peut avoir plus de changements. Dans certaines compétitions comme l'UEFA, ils disputent des premiers tours éliminatoires, puis une phase de groupe, puis une élimination à nouveau, ce qui se traduirait par 3 tours différents. Le résultat final devrait être une liste de tous les tours actuellement actifs pour chaque saison. – yoda

+0

Bon à savoir, mais je suis toujours aussi désemparé, désolé. –

Répondre

2

Supposons que les définitions de tableau ci-dessous (sans indices appropriés ou contraintes)

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) 
) 

et certaines données échantillons

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 ') 

-vous un temps fixe/date (fd) et que vous souhaitez les enregistrements ayant cette fd entre start_date et end_date. BETWEEN ... AND ... teste exactement cela et travaille avec des valeurs date/heure. E.g.

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

retourner les dossiers pour tous les tours (pour toutes compétitions confondues) à ce moment-là.
Maintenant, vous vous inscrivez sur le season_id avec la table des saisons. Et limitez les résultats à un certain competition_id (si vous voulez).

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 

edit: désolé, mal interprété la question .... En supposant que vous connaissez le competition_id et ont une date fixe (2009-08-16), vous pouvez obtenir la saison.id avec

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

vous pouvez maintenant JOIN sur season.id = rounds.season_id pour obtenir tous les tours cette saison.

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 

(tours: id 7,8,9 dans ce cas).
L'option la plus simple pour limiter le résultat au round.id le plus élevé est de laisser MySQL ordonner des rounds par rounds.id dans l'ordre décroissant et de limiter le résultat à un enregistrement.

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 

utilisation EXPLAIN SELECT ... pour vous assurer que la requête n'est pas trop inefficace ...

+0

Merci, cela m'a rappelé que les champs de date dans mes tableaux sont VARCHAR, pas de date, et c'est pourquoi je devrais probablement les convertir avant la comparaison. Quoi qu'il en soit, cela a aidé, mais j'ai encore besoin de savoir comment obtenir le dernier tour au cas où cela ne correspondrait pas. – yoda

+0

Merci encore, cela n'a pas correspondu entièrement à mes besoins mais m'a donné les lumières à la sollicution, alors j'accepte votre réponse. À votre santé! – yoda