Je veux faire le résultat de la table Scheda_atleta pour chaque joueur et faire une table HTML avec le meilleur résultat. J'ai deux tables:
premier nommé: at
+----+----------------+
| id | nome_e_cognome |
+----+----------------+
| 1 | Tom Tom |
| 2 | Jerry |
+----+----------------+
et seconde: scheda_atleta
+----+--------+----------+----------------+-----------+
| id | atleta | fs_score | qualificazione | categoria |
+----+--------+----------+----------------+-----------+
| 1 | 1 | 11,25 | 1 | 1 |
| 2 | 1 | 10,55 | 2 | 1 |
| 3 | 2 | 14,32 | 1 | 1 |
| 4 | 2 | 12,33 | 3 | 1 |
+----+--------+----------+----------------+-----------+
J'essaie ceci PHP code ci-dessous, mais ne fonctionne pas:
$db = JFactory::getDBO();
$bestAthleteScores = $db->getQuery(true)
->select($db->qn(["scores1.atleta", "scores1.fs_score","scores1.qualificazione","scores1.categoria"]))
->from($db->qn("scheda_atleta", "scores1"))
->leftJoin($db->qn("scheda_atleta", "scores2")
. " ON " . $db->qn("scores1.atleta") . " = " . $db->qn("scores2.atleta")
. " AND " . $db->qn("scores1.fs_score") . " < " . $db->qn("scores2.fs_score")
)
->where($db->qn("scores2.fs_score") . " IS NULL")
->where($db->qn("scores1.qualificazione") ."=". 1)
->where($db->qn("scores1.categoria"). ' IN (' . implode(',', $db->quote(array(1,99,100))) . ')' )
->order($db->qn("scores1.fs_score") . " DESC");
$rankVariable = $db->getQuery(true)
->select("@i := 0");
$rankedBestScores = $db->getQuery(true)
->select($db->qn("fs_score") . ",@i := @i + 1 AS " . $db->qn("rank"))
->from("(" . $bestAthleteScores . ") AS " . $db->qn("best_athlete_scores"))
->join("CROSS", "(" . $rankVariable . ") AS " . $db->qn("rank_variable"))
->order($db->qn("best_athlete_scores.fs_score") . " DESC");
$bestScoreRanks = $db->getQuery(true)
->select($db->qn("fs_score") . ", MIN(" . $db->qn("rank") . ") AS " . $db->qn("rank"))
->from("(" . $rankedBestScores . ") AS " . $db->qn("ranked_best_scores"))
->group($db->qn("fs_score"));
$query = $db->getQuery(true)
->select(
$db->qn(
["best_score_ranks.rank", "athlete_profile.nome_e_cognome", "athlete_profile.id", "athlete_scores.fs_score"],
[null, "athlete_name", "athlete_id", "best_score"]
)
)
->from($db->qn("at", "athlete_profile"))
->innerJoin($db->qn("scheda_atleta", "athlete_scores")
. " ON " . $db->qn("athlete_profile.id") . " = " . $db->qn("athlete_scores.atleta"))
->innerJoin("(" . $bestScoreRanks . ") AS " . $db->qn("best_score_ranks")
. " ON " . $db->qn("athlete_scores.fs_score") . " = " . $db->qn("best_score_ranks.fs_score"))
->where($db->qn("qualificazione")." =". 1)
->where($db->qn("categoria") . ' IN (' . implode(',', $db->quote(array(1,99,100))) . ')' )
->group($db->qn("athlete_profile.id"))
->order($db->qn("rank"));
$query->setLimit(24);
$db->setQuery($query);
$db->execute();
$query = $db->loadAssocList();
//echo "<pre>" , var_export($db->loadAssocList(), true) , "</pre>";
?>
<table class="category table table-striped table-bordered table-hover table-noheader">
<tr>
<th>nr</th>
<th>Atleta</th>
<th>RANK</th>
</tr>
<tbody>
<tr>
<?php foreach ($query as $result){ ?>
<td><?php echo($result['rank']); ?></td>
<td><?php echo($result['athlete_name']); ?></td>
<td><?php echo($result['best_score']); ?> </td>
</tr><?php } ?>
</tbody></table>
I would like to get this HTML table result (best result of 4 races):
+-----+-------------+------------+
| nr. | Player Name | Best score |
+-----+-------------+------------+
| 1 | Jerry | 14,32 |
| 2 | Tom Tom | 11,25 |
+-----+-------------+------------+
etc. Mais mon code ne fonctionne pas, sautez certaines données. Où suis-je tort?
[.____] Joomla! 3.9.21 Stable et MySQL 5.7
Ce SQL brut fonctionnerait si ma version de DB prend en charge RANK() OVER()
:
SELECT
RANK() OVER (ORDER BY MAX(fs_score) desc) AS nr,
nome_e_cognome AS "Player Name",
MAX(fs_score) AS "Best score"
FROM scheda_atleta
INNER JOIN at on at.id=scheda_atleta.atleta
GROUP BY at.id, nome_e_cognome
mais je veux générer le même ensemble de résultats en utilisant les méthodes d'assistance de la requête de la requête de Joomla.
J'ai modifié ma réponse à partir de Comment définir une variable MySQL définie par l'utilisateur et incrémenter pour produire des valeurs de classement avec jdatabaseQuery? et ajouté des sous-candidats supplémentaires pour obtenir les meilleurs scores pour chaque athlète.
Je recommande vivement d'utiliser un "classement gappel" car il représente plus précisément les performances des athlètes - en particulier dans les cas de cravates. Malheureusement, cette amélioration de la qualité des résultats vient avec un coût d'augmentation de la complexité/sophistication de la requête.
Essentiellement, il y a 3 tables jointes. Le athlete_profile
Tableau, une table dérivée contenant le meilleur score de chaque athlète, puis une autre table dérivée contenant le rang attribué à chaque meilleur score.
Testé JOOMLA Code: (Remonter, c'est un whopper)
$db = JFactory::getDBO();
// cache repeated values to prevent redundant method calls
$qn__fs_score = $db->qn("fs_score");
$qn__atleta = $db->qn("atleta");
$qn__all_scores_atleta = $db->qn("all_scores.atleta");
$qn__all_scores_fs_score = $db->qn("all_scores.fs_score");
$qn__rank = $db->qn("rank");
// prepare the where conditions to be applied at multiple positions
$wheres = [
$db->qn("qualificazione"). " = 1",
$db->qn("categoria"). ' IN (' . implode(',', $db->q([1,99,100])) . ')'
];
$personal_bests = $db->getQuery(true)
->select($qn__atleta . ", MAX(" . $qn__fs_score . ") AS " . $qn__fs_score)
->from($db->qn("scheda_atleta"))
->where($wheres)
->group($qn__atleta);
$bestAthleteScores = $db->getQuery(true)
->select($qn__all_scores_atleta . ", MAX(" . $qn__all_scores_fs_score . ") AS " . $qn__fs_score)
->from($db->qn("scheda_atleta", "all_scores"))
->innerJoin("(" . $personal_bests . ") " . $db->qn("personal_bests")
. " ON " . $qn__all_scores_atleta . " = " . $db->qn("personal_bests.atleta")
. " AND " . $qn__all_scores_fs_score . " = " . $db->qn("personal_bests.fs_score")
)
->where($wheres)
->group($db->qn("all_scores.atleta"))
->order($qn__all_scores_fs_score . " DESC");
$rankVariable = $db->getQuery(true)
->select("@i := 0");
$rankedScores = $db->getQuery(true)
->select($qn__fs_score . ", @i := @i + 1 AS " . $qn__rank)
->from("(" . $bestAthleteScores . ") AS " . $db->qn("best_athlete_scores"))
->join("CROSS", "(" . $rankVariable . ") AS " . $db->qn("rank_variable"));
$query = $db->getQuery(true)
->select([
$db->qn("athlete_profile.nome_e_cognome", "athlete_name"),
$db->qn("athlete_profile.id", "athlete_id"),
"MIN(" . $db->qn("ranked_scores.rank") . ") AS " . $qn__rank,
"MAX(" . $db->qn("ranked_scores.fs_score") . ") AS " . $db->qn("best_score")
])
->from($db->qn("at", "athlete_profile"))
->innerJoin("(" . $personal_bests . ") " . $db->qn("athlete_bests")
. " ON " .$db->qn("athlete_profile.id") . " = " . $db->qn("athlete_bests.atleta")
)
->innerJoin("(" . $rankedScores . ") AS " . $db->qn("ranked_scores")
. " ON " . $db->qn("athlete_bests.fs_score") . " = " . $db->qn("ranked_scores.fs_score")
)
->group($db->qn(["athlete_id", "athlete_name"]))
->order($qn__rank);
echo $query->dump(); // testing only, don't do this when live/public
$db->setQuery($query);
$db->execute();
echo "<pre>" , var_export($db->loadAssocList(), true) , "</pre>";
C'est la requête rendue: ( DB-Fiddle Demo * Notez l'écart au rang 38)
SELECT `athlete_profile`.`nome_e_cognome` AS `athlete_name`, `athlete_profile`.`id` AS `athlete_id`, MIN(`ranked_scores`.`rank`) AS `rank`, MAX(`ranked_scores`.`fs_score`) AS `best_score` FROM `at` AS `athlete_profile` INNER JOIN ( SELECT `atleta`, MAX(`fs_score`) AS `fs_score` FROM `scheda_atleta` WHERE `qualificazione` = 1 AND `categoria` IN ('1','99','100') GROUP BY `atleta` ) `athlete_bests` ON `athlete_profile`.`id` = `athlete_bests`.`atleta` INNER JOIN ( SELECT `fs_score`, @i := @i + 1 AS `rank` FROM ( SELECT `all_scores`.`atleta`, MAX(`all_scores`.`fs_score`) AS `fs_score` FROM `scheda_atleta` AS `all_scores` INNER JOIN ( SELECT `atleta`, MAX(`fs_score`) AS `fs_score` FROM `scheda_atleta` WHERE `qualificazione` = 1 AND `categoria` IN ('1','99','100') GROUP BY `atleta` ) `personal_bests` ON `all_scores`.`atleta` = `personal_bests`.`atleta` AND `all_scores`.`fs_score` = `personal_bests`.`fs_score` WHERE `qualificazione` = 1 AND `categoria` IN ('1','99','100') GROUP BY `all_scores`.`atleta` ORDER BY `all_scores`.`fs_score` DESC ) AS `best_athlete_scores` CROSS JOIN ( SELECT @i := 0 ) AS `rank_variable` ) AS `ranked_scores` ON `athlete_bests`.`fs_score` = `ranked_scores`.`fs_score` GROUP BY `athlete_id`, `athlete_name` ORDER BY `rank`
Certes, il s'agit tellement de convolution que cela peut poser la question "Pourquoi ne pas tirer tous les enregistrements et effectuer ce processus dans PHP?".
Eh bien, si vous l'avez fait, je ne voudrais probablement pas vous blâmer - mais il est probable que la solution PHP soit complexe/compliquée également.
Cette solution n'est pas pour le faibles-de-cœur, mais j'espère que j'ai nommé et expliqué les choses assez bien pour exprimer le pourquoi et la manière de cette technique.
Votre requête écrite à l'aide de la requête Builder:
$db = JFactory::getDbo();
$query = $db->getQuery(true)->select(
[
'RANK() OVER (ORDER BY MAX(' . $db->quoteName('fs_score') . ') DESC) AS ' . $db->quoteName('nr'),
$db->quoteName('nome_e_cognome', 'Player Name'),
'MAX(' . $db->quoteName('fs_score') . ') AS ' . $db->quoteName('Best score'),
]
)
->from($db->quoteName('scheda_atleta'))
->join('INNER', $db->quoteName('at') . ' ON ' . $db->quoteName('at.id') . ' = ' . $db->quoteName('scheda_atleta.atleta'))
->group(
[
$db->quoteName('at.id'),
$db->quoteName('nome_e_cognome'),
]
);
$db->setQuery($query);
Utilisez $db->loadObjectList()
ou $db->loadAssocList()
Pour charger les résultats en tant que tableau d'objets ou une matrice de tableaux associatifs, respectivement.
Remarque, afin d'exécuter des requêtes à Joomla, ne devez pas nécessairement utiliser le constructeur de requêtes. Vous pouvez transmettre votre chaîne SQL directement sur le pilote de base de données setQuery()
Méthode:
$db = JFactory::getDbo();
$db->setQuery('SELECT RANK() OVER (ORDER BY MAX(fs_score) desc) AS nr...');
$results = $db->loadObjectList();