Bonjour,

Vu que je suis incapable d'exprimer simplement mon problème avec des mots je vais aller droit au but :

Je travaille sur la vue suivante qui varie quotidiennement:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 > select * from top_activites;
id | score
86 | 7899
168 | 4689
78 | 3859
...
Je dois fournir (dans une vue) en fonction de chaque jour du mois les 5ènieme meilleures activités :
Soit N le jour du mois : je dois fournir les activités entre 5 * (N - 1) et 4 + 5 * (N - 1)

En gros la requête devrait avoir cette tronche :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
SELECT *
FROM top_activites
LIMIT 5 * (dayofmonth(current_date) - 1), 4 + 5 * (dayofmonth(current_date) - 1)
Problème la doc mysql indique que limit ne marche qu'avec des constantes ....

J'ai donc pensé à deux choses.
La première c'est donc de simuler le comportement de limite avec un encadrement du score , donc si on est le premier jour du mois il faut prendre tous les tuples dont le score est entre le 1er et le 4 meilleur score, le deuxième jour entre le 5e et le 9e etc etc , comme suit :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
SELECT *
FROM top_activites
WHERE score <= (SELECT CASE
                           WHEN dayofmonth(current_date) = 1
                           THEN (SELECT score 
                                     FROM top_activites
                                     LIMIT 0,1)
                           WHEN dayofmonth(current_date) = 2
                           THEN (SELECT score 
                                     FROM top_activites
                                     LIMIT 5,1)
                          ... on continue 31 fois
AND score >=     (SELECT CASE
                            WHEN dayofmonth(current_date) = 1
                           THEN (SELECT score 
                                     FROM top_activites
                                     LIMIT 4,1)
                          WHEN dayofmonth(current_date) = 2
                           THEN (SELECT score 
                                     FROM top_activites
                                     LIMIT 9,1)
etc etc
Déjà ça marche à moitié si on a des scores égaux ...
Et franchement ça m'a fait mal au coeur de faire ça mais c'est la seul solution viable que j'ai pu trouver ....

Ma deuxième idée est plus simple mais je perds le dynamisme de ma vue :
Je dois donc exécuter ce code tous les jours ... :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
 
DROP TABLE IF EXISTS top_tmp
CREATE TABLE top_tmp(id int unsigned auto_increment, id_activite int unsigned, score int unsigned);
INSERT IGNORE INTO top_tmp (id_activite, score) SELECT * FROM top_activites;
CREATE VIEW static_fail AS
  SELECT id_activite, score 
  FROM top_tmp
  WHERE id >= 5 * (dayofmonth(current_date) - 1)
  AND id <= 5 * (dayofmonth(current_date) - 1) + 4
Je pensais au début utiliser un "id de vue" mais seul oracle en dispose ...
Malgré qu'on peut le simuler comme suit, je n'ai pas réussi à utiliser une colonne dépendant d'une variable
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
          SELECT id_activite, 
                       score,
                       (@i := @i + 1) AS rang
          FROM top_activites, 
                    SELECT (@i := 0) AS t
Quoi que je fasse rang est inutilisable dans mes clause where :/


Une autre idée lu sur un post mysql serait de faire une grande table avec des id bigint unsigned de 1 à l'infinie et donc de faire une jointure entre ma vue (classée sur le score) et cette table pour ajouter donc un "id auto increment" sur la vue ... mais après avoir testé tous les types de jointure j'ai pas réussi



Dans tous les cas j'ai l'impression de faire des trucs vraiment pas terrible ...
C'est pourquoi je poste ici afin de savoir si quelqu'un à déjà rencontré un problème similaire et aurait trouvé une meilleure solution !

Je suis prêt à fournir d'avantage de précisions si nécessaire.
En vous remerciant d'avance.
Cdt.