10
votes

Comment faire la différence entre les valeurs spécifiques dans SQL?

hey les gens, désolé c'est un peu une question plus longue ...

J'ai une table avec les colonnes suivantes:

[chatide] [utilisateur] [Caredon] [Caredon] [ Texte]

Ce que je dois trouver est le temps de réponse moyen pour un ID utilisateur donné, à un autre ID utilisateur spécifique. Donc, si mes données ressemblent à: xxx

... Puis je dois voir que Susan a une durée de réponse moyenne de (20 + 6) / 2 => 13 secondes à John, et John a une moyenne de (9/1) => 9 secondes à Susan.

Je ne suis même pas sûr que ce peut faire être fait dans la logique basée sur l'ensemble , mais si quelqu'un a des idées, ils seraient très appréciés!


5 commentaires

Beaucoup plus facile à faire défini en fonction de de retard et lead je pense. Votez pour cela ici


Existe-t-il une limite au nombre d'utilisateurs dans un contexte chatide? I.e. Pour un seul chatide, il n'y aura que deux utilisateurs (comme votre exemple) ou peut-il y avoir un nombre illimité d'utilisateurs?


Il peut y avoir plus de 2, l'exemple a été simplifié.


Pouvez-vous fournir un exemple moins simplifié alors? Si vous avez 3 messages dans l'ordre d'Alice, Bob et Charles Comment savez-vous si Charles répondait à Bob ou à Alice?


Vous pouvez supposer qu'un message d'un utilisateur est en réponse au message le plus récent d'un autre utilisateur, de sorte que le boîtier d'utilisation simplifié est tiré.


6 Réponses :


8
votes

Je n'ai pas de PC pour vérifier la syntaxe ou quoi que ce soit, mais je pense que cela devrait vous donner un lieu de départ: xxx

essentiellement, l'idée est d'ajouter des numéros de ligne aux données Donc, vous pouvez rejoindre une ligne à la ligne suivante (vous avez donc une déclaration suivie de sa réponse immédiate). Une fois que vous avez rejoint les lignes, vous pouvez obtenir le temps écoulé entre les deux entrées, puis regrouper les données par le chattid (je suppose que les délais entre des discussions séparées ne sont pas pertinentes) et les deux utilisateurs. Comme si je l'ai dit, ce n'est qu'un lieu de départ que je suis sûr qu'il peut y avoir des critères et / ou des bogues supplémentaires dans ma requête :)


6 commentaires

Oups, je viens de modifier mon SQL et que l'original peut être meilleur; Je laisserai tel quel et vous pouvez voir l'historique de modification pour voir l'autre requête. La requête actuelle vous dira que John ajuste XX secondes pour répondre à quiconque, où la version précédente dirait que John Seconds Seconds XX pour répondre à Susan et Susan moyennant des secondes après avoir répondu à Jean, etc. (ce qui semble plus comme ce que vous avez demandé à l'origine) .


S'avère que ma question était inexacte (je voulais avoir le temps de réponse pour John d'être relatif au message premier de Susan, donc 43/2 secondes, mais depuis la réponse d'origine ici a répondu réellement à la question (tout à fait je pourrais ajouter), vous obtenez les points :).


+1 * SLAP-on-The-Brow * Chris Shaffer a la meilleure réponse, pourquoi je suis tellement enfer à tirer parti de la logique de mon autre réponse Stackoverflow.com/questions/1610599/... < / a> à cette réponse


concernant Susan 43/2 (ou est-ce 49/2 49 étant 43 + 6), le seul facteur de rachetage de ma solution est qu'il pourrait être facilement façonné pour Jvenema's Problème réel (temps de réponse relatif au message premier (bien que n'était pas indiqué dans la question initiale)), changez simplement le max en min. Quoi qu'il en soit, il est laissé comme un exercice pour les sales :-)


@Michael - Il est 43 - Le temps que nous essayons de mesurer est combien de temps il faut pour répondre, donc la réponse première au message premier d'un utilisateur donné est en fait Ce que nous recherchons (bien que dans ma question initiale, j'ai demandé la réponse réponse au message dernier ).


3:00:43 (réponse) - 3:00:00 (premier message) == 43. 3:01:08 (réponse) - 3:01:02 == 6. C'est là que j'ai eu le 49. Quoi qu'il en soit, le Le problème réel n'est pas bien défini, alors je propose 49, c'est juste ma façon de déduire le vrai problème (temps moyen (et basé sur les premières réponses aux premiers messages), et le problème ne concerne pas la moyenne < / i> plus s'il n'y a pas d'autres numéros sont impliqués)




2
votes

On dirait que vous avez besoin d'un curseur pour traverser chaque ligne et recherchez le changement d'utilisateur dans l'enregistrement et obtenez la différence de ce temps, et rangez-la quelque part (table TEMP peut-être) et l'agrégez-le plus tard.

Je crois que cela peut être fait dans TSQL, la logique serait quelque chose comme: xxx

Je suis sûr que vous pouvez déterminer comment déclarer tous les paramètres.


4 commentaires

+1 Cela a l'avantage d'une analyse via les données. Je pense que la syntaxe est un peu éteinte. A définitivement besoin d'une commande par sur la sélection.


Les curseurs en SQL ne sont pas recommandés.


@Chris - généralement pas, mais parfois, ils sont la meilleure solution à moins que Microsoft implémente complètement la clause sur . Les totaux en cours d'exécution étant un exemple classique. Quelques comparaisons de performance ici Aucune idée qui serait la plus efficace dans ce cas particulier (curseurs vs joints sur rownumber = rownumber + 1)


D'accord. Dans de très rares cas, un curseur est justifié.



3
votes

Essayez quelque chose de simple comme ce qui suit avant de vous déplacer dans des curseurs.

declare @operator varchar(50)
set @operator = 'john'
declare @customer varchar(50)
set @customer = 'susan'
declare @chatid int
set @chatid = 1

declare @t table (chatid int, username varchar(50), responsetime int)

insert @t (chatid, username, responsetime)
select ChatId, 
    Username,
    datediff(second, 
    CreatedOn,
    (
        select min(createdon)
        from chatlog
        where createdon > cl.createdon
        and username = @customer
              and chatid = @chatid
    ))
from ChatLog cl
where chatid = @chatid and username = @operator

insert @t (chatid, username, responsetime)
select ChatId, 
    Username, 
    datediff(second, 
    CreatedOn,
    (
        select min(createdon)
        from chatlog
        where createdon > cl.createdon
        and username = @operator
              and chatid = @chatid
    ))
from ChatLog cl
where chatid = @chatid and username = @customer

select chatid, username, avg(responsetime) as avgresponsetime 
from @t
group by chatid, username
order by username


2 commentaires

Ne pensez pas que cela produira le jeu de données que l'OP recherche.


Je savais en quelque sorte que le premier ne fonctionnerait pas, je suggère simplement que des déclarations de sélection simples doivent être considérées avant d'utiliser des curseurs. Devrait probablement avoir ajouté que comme un commentaire au lieu d'une solution, je suis donc allé de l'avant et j'ai mis en œuvre une solution approximative.



1
votes

Essayez ceci: xxx pré>

données d'échantillon: p> xxx pré>

sortie: p> xxx pré> Le regroupement: p> xxx pré>

sortie: p> xxx pré>

le résultat groupé: p> xxx

sortie: p> xxx pré>

chat et réponses: p> xxx pré>

sortie: p>

 responded_by | responded_to |   sum    | count | average_response_to_person 
--------------+--------------+----------+-------+----------------------------
 susan        | john         | 00:00:26 |     2 | 00:00:13
 john         | susan        | 00:00:09 |     1 | 00:00:09
(2 rows)


0 commentaires

1
votes

Cela permettra de faire le travail, mais je ne suis pas sûr de savoir comment ça va échoué: xxx

4 record (s) sélectionné (Fetch MetaData: 0ms] [Fetch Data: 0MS]

Ça devrait être d'accord avec un index sur (chat_id, log_id).

Si vous souhaitez éliminer les mêmes réponses, tout ce dont vous avez besoin est un! = dans l'externe où la clause : xxx


0 commentaires