salut,
Coté html il faut commencer par sortir la déclaration de la table de la boucle while.
en schématisant :
<table>
do {
...
}while();
</table>
pourquoi do / while plutôt que while ?
la différence
ici
tu devrais utiliser un while car la tu as des erreurs sur la variable $rw_Rs10 si la requête ne retourne pas de données.
dans le même genre évite les shorts tags
coté SQL : se serait pas mal d'avoir une jointure normalisée parce que la c'est un peu la foire ton prédicat on ne sais pas trop qui fait quoi
c'est quand même plus lisible ainsi
SELECT Sport, Disicipline, Heure, Finale, Sexe, Epreuve, Obs
FROM programme
join jour using(JourID)
join epreuve using(EpreuveID)
join competition using(CompetID)
join sexe using(SexeID)
WHERE JourID=41
AND programme.JeuxID=63
ORDER BY competition.Sport, competition.Disicipline, epreuve.Epreuve
L'extension mysql est dépréciée depuis pas mal de temps et supprimée de php 7 (dernière version qui a maintenant plus d'un an) ce serait pas mal de migre vers mysqli ou PDO pour préparer l'avenir (comme une mise à jour de php

)
Pour ce qui est des données.
soit tu dédoublonnes tes données avant (est-ce qu'un distinct SQL ne ferais pas l'affaire ?) soit tu gères ce que l'on appel une césure.
en claire tu gardes l'état précédent dans une variable (en dehors de la boucle) et tu compares avec l'actuel
Pour faire "bien" il est possible d'utiliser l'attribut rowspan sur ta cellule mais pour cela il faut savoir combien tu as de lignes à afficher à chaque fois (et ne pas afficher la première colonne pour les lignes suivantes).
Pour faire cela le plus simple c'est de gérer un tableau que tu remplis a partir des données de la requête sql tu t'en servira ensuite pour l'affichage.
cela peux donner quelque chose de ce genre
<?php
mysql_select_db($database_jo, $jo);
$query_Rs10 = "SELECT Sport, Disicipline, Heure, Finale, Sexe, Epreuve, Obs
FROM programme
join jour using(JourID)
join epreuve using(EpreuveID)
join competition using(CompetID)
join sexe using(SexeID)
WHERE JourID=41
AND programme.JeuxID=63
ORDER BY competition.Sport, competition.Disicipline, epreuve.Epreuve";
$Rs10 = mysql_query($query_Rs10, $jo) or die(mysql_error());
$data = [];
while ($row_Rs10 = mysql_fetch_assoc($Rs10)) {
$data[strtolower($row_Rs10['Sport'] . $row_Rs10['Disicipline'])][$row_Rs10['Heure']][] = $row_Rs10;
}
mysql_free_result($row_Rs10);
// alors la data est un tableau indexé par sport et discipline qui contient un tableau indéxé par les heures qui va contenir une tableau
// ce tableau correspond aux données pour l'heure dans un sport et une discipline données
?>
<h3><a href="#">10 févier</a></h3>
<div>
<table>
<?php
foreach ($data as $sport) {
$nbHour = count($sport);
$firstColumnPrint = false;
$oldHeure = null;
foreach ($sport as $heure) {
$secondColumnPrint = false;
$nbData = count($heure);
foreach ($heure as $d) {
echo '<tr>';
if (!$firstColumnPrint) {
echo <<<html
<td class="jour_sport" rowspan="{$nbHour}">{$d['Sport']}<br/>{$d['Disicipline']}</td>
html;
$firstColumnPrint = true;
}
if (!$secondColumnPrint) {
echo <<<html
<td class="heure" rowspan="{$nbData}">{$d['Heure']}</td>
html;
$firstColumnPrint = true;
}
echo '<td>';
if ($row_Rs10['Finale'] == 1) {
echo '<strong><em>';
}
echo $row_Rs10['Sexe'], ' ', $row_Rs10['Epreuve'], ' ', $row_Rs10['Obs'];
if ($row_Rs10['Finale'] == 1) {
echo '</em></strong>';
}
echo '</td>';
}
}
}
?>
</table>
</div>
@+
Il en faut peu pour être heureux ......