Help query di conteggio

martedì 20 maggio 2008 - 16.59

HereticMaikey Profilo | Newbie

Ciao ragazzi, sono Michele.
Sto impazzendo da due ore cercando di formulare una query che mi permetta di conteggiare il numero di messaggi scambiati fra due utenti. Per essere piu chiaro faccio un esempio:

Mittente - Destinatario - Msg
A - B -------- Ciao B!
A - B -------- Come va?
A - B -------- Spero bene.
B - A -------- Si tutto ok.
C - D -------- Ciao D!
C - D -------- Come va?
D - E -------- Ciao E!
D - C -------- Tutto bene.

Devo contare il numero di messaggi scambiati fra A e B (in questo caso 4), fra C e D (3) e fra D ed E (1), senza però utilizzare nella clausola WHERE condizioni del tipo:

WHERE (mittente='A' and destinatario='B') or (mittente='B' and destinatario='A')

Cioè non devo mettere esplicitamente il mittente o il destinatario.
Ho pensato a join e raggruppamenti vari, ma non riesco a giungere ad una soluzione.
C'è qualcuno che può illuminarmi?
Vi ringrazio anticipatamente!
Michele

Brainkiller Profilo | Guru

>C'è qualcuno che può illuminarmi?
>Vi ringrazio anticipatamente!

Ciao Michele,
ma la tabella in cui sono immagazzinate queste informazioni che struttura ha (tipo dati colonne) ? Immagino non ci siano le lettere A, B, C, ma magari degli ID numerici corrispondenti ai vari utenti ? Cioè quindi sono due colonne di Tipo Int o è una colonna unica varchar ? o altro ?

David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/

HereticMaikey Profilo | Newbie

Innanzitutto grazie per la risposta!
Si esatto. Ovviamente non contiene le lettere, ma una chiave primaria di tipo INT contatore, gli id di tipo GUID (o uniqueidentifier che dir si voglia) dei rispettivi mittente e destinatari ed altri campi contenenti varie info sul messaggio.
Per intenderci:

Messaggi(IdMsg, IdRichiesta, IdMittente, IdDestinatario, CorpoMsg, dataMsg, dataLettura, ecc...)

Spero sia stato chiaro, ma più di tutto spero possiate darmi na mano.
Grazie
Michele

Brainkiller Profilo | Guru

>Spero sia stato chiaro, ma più di tutto spero possiate darmi
>na mano.

Io proverei a fare così, la query si complica ma si semplifica la parte di WHERE.
Allora ho fatto questa simulazione, tabella con colonne IdFrom e IdTo numeriche int.
Con questi dati:

IdFrom - IdTo
1 2
1 2
2 1
3 4
3 4
4 3
5 9
2 1

Se io lancio questa query:

SELECT CASE When IdFrom<IdTo THEN IDfrom ELSE IDto END AS IdFrom, CASE When IdFrom>IdTo THEN IDfrom ELSE IDto END AS IdTo from msg

che contiene un CASE mi consente di uniformare le comunicazioni tra le stesse persone, esempio quelle tra 1 e 2 e 2 e 1 me le trasforma tutte come tra 1 e 2. In questo modo:

1 2
1 2
1 2
3 4
3 4
3 4
5 9
1 2

Ora questa query posso salvarla in una View ed eseguire:

SELECT COUNT(*) FROM View WHERE IDFrom=1 and IDTo=2

e mi restituirà 4 (cioè due tra 2 e 1 e due tra 1 e 2).

Se la vuoi invece in formato esteso senza l'uso della vista:

SELECT COUNT(*) FROM (select CASE When IdFrom<IdTo THEN IDfrom ELSE IDto END AS IdFrom, CASE When IdFrom>IdTo THEN IDfrom ELSE IDto END AS IdTo from msg) b where IDFrom=1 and IDTo=2

Ciao

David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/

HereticMaikey Profilo | Newbie

Grazie mille per la risposta! La tua soluzione dovrebbe funzionare alla grande! Devo magari sostituire la condizione where ed aggiungere un group by alla query, per evitare, come detto in precedenza, di indicare esplicitamente il mittente ed il destinatario.
Ora faccio una prova e se tutto va bene, posto la soluzione finale!
Grazie per avermi portato sulla strada giusta!

HereticMaikey Profilo | Newbie

FUNZIONA!
Grazie ancora per la dritta! Ecco la query che ho utilizzato:

SELECT idMittente, idDestinatario, COUNT(*) AS MessaggiScambiati
FROM

(SELECT case when idMittente < idDestinatario then idMittente else idDestinatario end AS idMittente, case when idMittente > idDestinatario then idMittente else idDestinatario end AS idDestinatario
FROM Messaggio) TabProva

GROUP BY idMittente, idDestinatario

Cosi facendo ottengo:
idMittente -- idDestinatario -- MessaggiScambiati
1 ------------- 2 ------------------ 10
2 ------------- 3 ------------------ 2

Brainkiller Profilo | Guru

>Grazie ancora per la dritta! Ecco la query che ho utilizzato:

Ottimo, prego.

>GROUP BY idMittente, idDestinatario

Infatti era quello che volevo consigliarti io.
Ma una volta che hai risolto il problema iniziale puoi sbizzarrirti ed estendere come vuoi.
Ciao

David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5