J'ai une table statistique pour la radio Internet (mySQL), il existe de telles colonnes:
J'ai besoin de sélectionner le pic d'auditeurs pour chaque jour, je veux dire nombre maximum d'auditeurs IP uniques simultanées. P>
et il serait également génial d'avoir du temps de début et de fin de ce pic . P>
Par exemple: p>
p> p>
4 Réponses :
SELECT
COUNT(*) AS listeners,
current.time_start, AS peak_start,
MIN(overlap.time_end) AS peak_end
FROM
yourTable AS current
INNER JOIN
yourTable AS overlap
ON overlap.time_start <= current.time_start
AND overlap.time_end > current.time_start
GROUP BY
current.time_start,
current.time_end
HAVING
MIN(overlap.time_end) < COALESCE((SELECT MIN(time_start) FROM yourTable WHERE timeStart > current.timeStart), current.time_end+1)
For each record, join on everything that overlaps.The MIN() of the overlapping records' time_end is when the first current listener stops listening.If that time is less than next occurance of a time_start, it's a peak. (Peak = start immediately followed by a stop)
Merci, essayé votre requête via phpmyadmin ... MySQL s'est arrêté pendant environ 10 minutes (il n'y a que 35 000 lignes dans la table) et aucun résultat n'a été renvoyé.
Peut-être que nous devons limiter les dates ou utiliser le regroupement de jour?
@ARTICOBANDURURININI - Y a-t-il des champs supplémentaires à rejoindre, et / ou est le time_end code> toujours le même jour que le time_start code>?
Aucun champ supplémentaire à rejoindre et time_end code> peut être le lendemain, par exemple. L'auditeur pourrait commencer à écouter la radio à 23h30 et à finir à 00h25 le lendemain
@ARTICOBANDURININI - Version légèrement différente ajoutée, pas sûr que ce sera beaucoup plus rapide. Y a-t-il une durée maximale pour tout auditeur?
La durée n'est pas limitée, certaines sessions d'écoute peuvent être plus longues qu'un jour ou même plus
@Articobandurinini - Les changements ont-ils aidé?
MySQL a dit: # 1054 - Colonne inconnue 'Current.Time_end' dans "Avoir la clause"
Le même ... 10 minutes de rotation et 100% CPU pour MySQLD - et le résultat est "Le serveur fermé la connexion sans envoyer de données".
Peut-être que ce serait plus facile si je change la structure de données après la suggestion de Max?
IMHO Il est plus simple de charger ces 35 000 rangées en mémoire, de les énumérer et de conserver un compte d'auditeur simultané à un moment donné. afin de pouvoir charger les données commandées par heure et que vous devriez simplement énumérer toutes les lignes de conserver une liste d'écoute de la propriété intellectuelle. P> Quoi qu'il en soit, comment envisagez-vous plusieurs connexions de la même adresse IP? mise à jour:
Vous n'avez pas besoin de changer la structure de base de données, il suffit d'utiliser un SQL différent pour charger les données P> à l'aide de ce SQL, vous devriez pouvoir charger toutes les données, puis énumérer toutes les lignes. Si StartStop = 1 C'est SOMONE qui commence à écouter -> Ajouter C'est IP de la liste des auditeurs et incrémenter les écouteurs comptent par 1 et dans la vérification de la boucle d'énumération lorsque vous atteignez le nombre maximum d'auditeurs simultanés p> p>
Ce serait plus simple si vous chargez la ligne dans le format suivant:
Il peut y avoir 10 auditeurs différents derrière une NAT en utilisant la même adresse IP. P>
Il est important que les lignes soient triées correctement. P>
Si StartStop = 0 c'est une personne qui arrête d'écouter -> Supprimer c'est IP de la liste des auditeurs et décrémenter le nombre d'écouteurs par 1 p>
Merci max! Au début, sur les multiples connexions. ICECAST est capable de suivre tous les auditeurs séparément, malgré la propriété intellectuelle, il ne s'agira donc que de plusieurs rangées dans la table avec la même adresse IP. Je peux changer la structure de données, mais pourriez-vous vous fournir le SQL pour cette nouvelle structure, car je ne suis pas assez bon dans une telle question ...
laisser aller à trouver un algorithme pour obtenir des résultats avec les meilleures performances.
time_start code> et time_end code>. Li>
ul> C'est mon approche du temps divisé. Je crée une vue pour simplifier la poste: p> xxx pré> Je vous suggère 2 index de base de données: p> xxx pré> pour éviter les tablescan. p>
- Comptez les auditeurs Peak Strort>: Rejoignez la table précédente avec votre table pour effectuer un raccomptage de pic à chaque point de contrôle: LI>
ul>
Ceci est mon approche pour les auditeurs de comptage par heure de contrôle: p> xxx pré> N'oubliez pas de créer un index de base de données sur votre_table (time_start, time_end)
-
à la recherche de maximum pic fort>: malheureusement mysql ne possède pas de fonctions analytiques, alors sur la partition code> n'est pas disponible et n'est pas un moyen de prendre maximum le pic sur une journée vue précédente. Ensuite, vous devriez obtenir un maximum de points de vue précédents. Il s'agit d'une opération tueur de performance forte>. Je vous suggère de faire cette opération et ensuite sur la logique de l'application et non dans la base de données. li>
ul> C'est mon approche pour obtenir max_peak par jour ( tueur de performance strong>): p> select
cast(p_time as date) as p_day,
min( p_time ) as slot_from,
max( p_time) as slot_to,
peak
from
peak_by_time_and_previous p
inner join
max_peak_by_day m
on cast(p.p_time as date) = m.p_day and
p.peak = m.max_peak
where
p.peak = p.previous_peak
group by cast(p_time as date)
- à la recherche de délais de fente strong>: à ce moment, vous avez
max_peak code> pour chaque jour, vous devez maintenant rechercher des temps de chèque continus code> avec même max_peak. Aussi mysql ne possède pas de fonctions statistiques ni CTE. Je vous suggère que ce code sera écrit sur la couche d'application. Mais, si vous voulez faire cela dans la solution de base de données, c'est un moyen ( Tauteur de performance d'avertissement Strong>): Li>
ul> Premier, EXTENDRE PEAK_BY_TIME CODE> Voir le pic précédent pour P_Time et pour P_Time précédent: P> create view time_split_extended as
select c.p_time, max( p.p_time) as previous_ptime
from
time_split c
inner join
time_split p
on p.p_time < c.p_time
group by c.p_time
create view peak_by_time_and_previous as
select
te.p_time,
te.previous_ptime,
pc.peak as peak,
pp.peak as previous_peak
from
time_split_extended te
inner join
peak_by_time pc on te.p_time = pc.p_time
inner join
peak_by_time pp on te.previous_ptime = pp.p_time
Ceci est essentiellement une implémentation de la réponse donnée par max ci-dessus. Pour la simplicité, je représenterai chaque épisode d'écoute comme une heure de départ et une longueur en tant que valeurs entières (elles pourraient être modifiées vers des quertimes réelles, puis les requêtes devraient être modifiées pour utiliser la date d'arithmétique.)
SET @idx=0;
SET @n=0;
SELECT (@idx := @idx + 1) as idx,
t,
(@n := @n + delta) as n
FROM
(SELECT start AS t,
1 AS delta
FROM episodes
UNION ALL
SELECT start + len AS t,
-1 AS delta FROM episodes
ORDER BY t) stage
+------+--------+------+
| idx | t | n |
+------+--------+------+
| 1 | 8 | 1 |
| 2 | 106 | 2 |
| 3 | 203 | 3 |
| 4 | 274 | 2 |
| 5 | 533 | 3 |
| 6 | 586 | 2 |
...
Pourriez-vous s'il vous plaît poster un exemple de script de génération de données que vous utilisez