0
votes

Quel type de jointure peut fusionner des enregistrements dans une seule table SQL?

J'ai besoin de trouver et de fusionner des enregistrements dans une table liée à la fois. La table enregistre l'activité utilisateur sur un site Web (heures de début de l'activité et d'activité).

J'essaie de fusionner à un enregistrement une activité dans une heure d'une autre activité par le même utilisateur. Donc, si le début d'un enregistrement est de 55 minutes après la fin de la même activité précédente de l'utilisateur, je fusionner cela pour faire un enregistrement. P>

J'ai essayé divers types de joints de soi pour y parvenir, mais Les résultats ne sont jamais parfaits. P>

en deux étapes, j'ai essayé ceci: p>

  1. Mise à jour d'une première mise à jour (fin de l'activité), de sorte que tous les enregistrements en une heure de l'autre ont un horodatage commun commun, qui est le dernier du groupe. p> li>

  2. Supprimez tous les derniers enregistrements du groupe, de sorte que seul le dernier enregistrement reste, maintenant avec le premier créé_at et le dernier mis à jour_at p> li> ol>

    - Définissez d'abord un temps de fin commun (mis à jour) pour toute activité par un utilisateur avec moins d'une heure entre p> xxx pré>

    si les données sont Comme ceci: p> xxx pré>

    i devrait obtenir ce résultat: p> xxx pré>

     exemple de données pour la fusion A> p>

    Nouvelles infos forts>. Cette requête recevra des résultats contenant les informations dont j'ai besoin: ID des sessions pour mettre à jour et fusionner. Mais comment mettre à jour la masse, lorsque la mise à jour de chaque ligne modifie potentiellement les mises à jour nécessaires sur d'autres lignes? P>

    SELECT b.id, b.user_id, b.created_at, b.updated_at, b.UpdatedAtOfSessionToMerge, b.IDofSessionToMerge FROM (SELECT
    UA1.id,
    UA1.user_id,
    UA1.created_at,
    UA1.updated_at,
    UA2.updated_at AS UpdatedAtOfSessionToMerge,
    UA2.id AS IDofSessionToMerge
    FROM users_activity UA1, users_activity UA2
    WHERE
    UA1.id <> UA2.id
        AND UA1.user_id = UA2.user_id
        AND UA1.created_at > DATE_SUB(UA2.updated_at,INTERVAL 1 HOUR)
        AND UA1.updated_at < UA2.updated_at
        AND UA1.created_at < UA2.updated_at
        ) b order by b.user_id;
    


5 commentaires

Comment savez-vous quand et quand ne pas fusionner? Je vois user_id 1222 avec 2 reCrds dans les résultats attendus. Pourquoi y a-t-il 2 et pas 1? ahh je vois maintenant heure w / in start


Donc, si vous avez une entrée à 13h00 à 13h45 et une à 14h15 et une à 3h15 ne sont que la 1ère deux fusionnées et les 2e deux fusionnées? Ou tous les 4 fusionnés sont-ils fusionnés sur la fusion sont un peu vagues, il serait plus facile de simplement grouper par yyyymmddhh24 ... mais je ne suis pas sûr que c'est ce que vous voulez.


Merci pour ces clarifications. S'il y a une lacune de plus d'une heure entre les sessions, ne fusionnez pas. Gap désigne la différence de temps entre mis à jour_at (fin) et le suivant (plus tard) créé_at (Démarrer).


Ok ... alors en utilisant mon exemple ci-dessus ... Les 1 & 1:45 fusionneraient. Les 1:14 et 2:15 fusionneraient les 2:15 et 3:15 fusionneraient. Donc, mes 4 disques deviendront 3 avec certains d'être dupliqués ... Ce n'est pas facile de faire parce que les règles manquent de précision ..


Droite. Également pas facile à faire car chaque fois qu'une ligne change (enlever ou mettre à jour un duplicata), nous devrions recalculer les résultats restants. J'ai posté une réponse ici qui fait le travail, mais pas élégamment. Encore très intéressé s'il existe un moyen plus propre d'identifier et de mettre à jour des lots d'enregistrements en fonction de leurs valeurs.


3 Réponses :


0
votes
SELECT min(ID) as ID, User_ID, Min(Created_At) Created_At, Max(Updated_At) as Updated_At
FROM Table
GROUP BY User_ID, DATE_FORMAT(Created_At, "%Y%m%d%H");
Would be close but I'm not sure I'm handling the "Hour" rollup the way you want.

0 commentaires

0
votes

Vous pouvez regrouper votre date en fonction d'un paramètre. En outre, il est toujours bon en termes de vitesse de traitement future pour commander vos données si vous le pouvez. Il rend également votre résultat de requête simplement plus agréable.

SELECT min(ID) as ID, User_ID, Min(Created_At) Created_At, Max(Updated_At) as Updated_At


3 commentaires

Gardez à l'esprit qu'ils veulent que User_id soit répertorié plusieurs fois si un utilisateur a une "heure" différente créée_ats ...


VRAI, D'accord Oui, je vois ce que vous avez fait avec le groupe Date_Format par temps également.


Sélectionnez min (ID) comme ID, user_id, min (créé_at) créé_at, max (mise à jour) comme mise à jour_at du groupe User_Activity par user_id; Oui, cela me fait la première et la dernière activité pour chacun utilisateur. J'ai besoin de les regrouper en lots d'enregistrements, séparés de pas plus d'une heure. Ça me dérange encore ...



0
votes

Ceci est une solution manuelle, suffisamment bonne pour un nettoyage ponctuel d'anciennes données de session. Il utilise deux jointures auto, donc il pourrait y avoir un moyen plus efficace de le faire.

étape 1 , retrouvez des lots de disques de session et de les unifier en leur donnant la même fin de session valeur (mise à jour_at) xxx

répétez cette requête jusqu'à ce qu'aucune ligne ne soit affectée

étape 2 , supprimez des enregistrements de session inutiles dans chaque lot unifié; xxx

répéter cette requête jusqu'à ce qu'aucune ligne ne soit affectée


0 commentaires