2010-09-16 6 views
2

Je regroupe des enregistrements en fonction de la proximité du temps. Ce que je fais en ce moment (horodatages unixtime),Un moyen efficace de séparer un groupe en enregistrements individuels

Tout d'abord je fais un sous sélection pour saisir des documents qui sont d'intérêt de moi,

(SELECT timestamp AS target_time FROM table WHERE something = cool) AS subselect 

Je veux regarder les dossiers qui sont proches à temps à ceux-ci,

SELECT id FROM table, subselect WHERE ABS(target_time - timestamp) < 1800 

Mais voici où j'ai frappé mon problème. Je veux seulement les disques où la différence de temps entre les enregistrements autour du target_time est> 20 minutes. Pour ce faire, je grouper par target_time et ajouter une section HAVING.

SELECT id FROM table, first WHERE ABS(target_time - timestamp) < 3600 
GROUP BY target_time HAVING MAX(timestamp) - MIN(timestamp) > 1200 

Cela tombe bien, et tous les disques que je n'aime pas sont partis, mais maintenant je ne le premier id du groupe, quand je veux vraiment tous les ids. Je peux utiliser GROUP_CONCAT mais cela me donne un désordre que je ne peux plus faire de requêtes. Ce que je voudrais vraiment obtenir tous les ids retournés de tous ces groupes qui sont créés. Ai-je besoin d'une autre instruction SELECT? Ou y a-t-il juste une meilleure façon de structurer ce que j'ai?

Merci,

Un code SQL.

+0

Que voulez-vous exactement? Vous dites d'abord que vous voulez regrouper par intervalle de temps. Vous faites cela et ensuite vous vous plaignez que vous obtenez un seul enregistrement par groupe, ce qui est ce que le groupe est censé faire (et ce que vous avez d'abord dit que vous voulez). Donc, je suis un peu confus. – jira

+0

Désolé, je suppose que ma question initiale a changé lorsque j'ai écrit le problème. Le vrai problème est que j'ai besoin de regrouper les enregistrements, afin d'utiliser des fonctions agrégées pour en supprimer certaines dont je n'ai pas besoin. Mais alors j'ai besoin de décomplexer? mes enregistrements afin que je puisse accéder aux identifiants individuellement. Et je ne connais pas la méthode la plus efficace pour cela. Je vais faire un montage rapide merci. –

Répondre

0

Mon hypothèse est que vous voulez une sortie qui ressemble à:

id1, timestamp1, fieldA, fieldB 
    id1, timestamp2, fieldA, fieldB 
    id2, timestamp3, fieldA, fieldB 
    id2, timestamp4, fieldA, fieldB 
    id3, timestamp5, fieldA, fieldB 
    id3, timestamp6, fieldA, fieldB 

mais l'horodatage de ces enregistrements est entre 1200 et 1800 secondes d'un « target_time » où quelque chose = cool?

SELECT data.id, data.timestamp, data.fieldA, data.fieldB, ..., data.fieldX 
    FROM events 
    JOIN data 
    WHERE events.something = cool_event -- Gives the 'target_time' of cool_event 
     AND ABS(event.timestamp - data.timestamp) BETWEEN 1200 and 1800 -- gives data records 'near' target time, but at least 20 minutes away. 

si les « données » et « événements » tableau sont la même table, puis utilisez simplement les noms d'alias de table, mais vous pouvez joindre à une table pour lui-même, alias « autojointure ».

SELECT data.id, data.timestamp, data.fieldA, data.fieldB, ..., data.fieldX 
    FROM events AS target, events AS data 
    WHERE target.something = cool_event -- gives the 'target_time' of cool_event 
     AND ABS(target.timestamp - data.timestamp) BETWEEN 1200 and 1800 -- gives data records 'near' target time, but at least 20 minutes away. 

Ceci semble à peu près exact, et ne nécessite aucun groupement ou agrégat.

Vous pouvez commander les données résultantes si nécessaire.

- J Jorgenson -

+0

Ce n'est pas tout à fait ce dont j'ai besoin. Disons que l'heure cible est minuit. Je veux tous les disques de 11: 30-12: 30. Mais disons quand je reçois ces disques, les seuls à ce moment-là sont de 11: 56-12: 05. Le temps d'étirement n'est pas assez long. Donc, je veux les identifiants de tous les enregistrements autour des heures cibles où le groupe est revenu s'étire plus de 20 minutes. Confus je sais. (D'où la prime). Merci quand même! –

1

Voyez si je vous corriger le problème:

Pour une ligne donnée dans une table, vous voulez connaître l'ensemble de lignes pour les enregistrements similaires si la gamme de horodatages pour ces enregistrements est supérieur à 20 minutes. Vous voulez le faire pour tous les identifiants de la table.

Si vous souhaitez simplement une liste des ids qui remplissent ces critères, il est assez simple:

donné une table comme:

create table foo (id bigint(4), section VARCHAR(2), modification datetime); 

vous pouvez faire:

select id, foo.section, min_max.min_modification, min_max.max_modification, abs(min_max.min_modification - min_max.max_modification) as diff 
from foo, 
(select section, max(modification) max_modification, min(modification) min_modification from foo as inner_foo group by section) as min_max 
where foo.section = min_max.section 
and abs(min_max.min_modification - min_max.max_modification) > 1800; 

Vous Effectuez une sous-sélection basée sur les critères 'lignes similaires' (dans ce cas, la section colonne) pour obtenir les horodatages minimum et maximum pour cette section. Cette min et max s'applique à tous les identifiants dans cette section. Par conséquent, pour la section «A», vous aurez une liste d'identifiants, même chose pour la section «B».

Questions connexes