Home Page
Articoli
Tips & Tricks
News
Forum
Archivio Forum
Blogs
Sondaggi
Rss
Video
Utenti
Chi Siamo
Contattaci
Username:
Password:
Login
Registrati ora!
Recupera Password
Home Page
Stanze Forum
SQL Server 2000/2005/2008, Express, Access, MySQL, Oracle
[SQLSrv] Query 'nidificate' del tipo "SELECT * FROM (select a from b w...
lunedì 12 marzo 2007 - 17.09
Elenco Threads
Stanze Forum
Aggiungi ai Preferiti
Cerca nel forum
Hamelin [FL]
Profilo
| Junior Member
65
messaggi | Data Invio:
lun 12 mar 2007 - 17:09
Saluti a tutti
Non so se la seguente domanda è banale o impossibile, ho provato a cercare in giro ma se cerco informazioni sulle query nidificate trovo solo quelle del tipo
SELECT *
FROM Tabella
WHERE Campo IN (SELECT * FROM T WHERE clausola)
che purtroppo non sono quello che mi interessa
E' possibile fare in una sola query una conta dei risultati di un'altra query? Qualcosa tipo
SELECT Count(*)
FROM
(SELECT Campo
FROM Tabella
WHERE clausola)
***********************
Se non fosse chiaro, un esempio pratico
CREATE TABLE Tabella
(Id int
DataLogin date
TipoUtente varchar)
INSERT INTO Tabella (Id, DataLogin, TipoUtente) VALUES (1, '01/01/2007', 'TipoA')
INSERT INTO Tabella (Id, DataLogin, TipoUtente) VALUES (1, '01/01/2007', 'TipoA')
INSERT INTO Tabella (Id, DataLogin, TipoUtente) VALUES (2, '01/01/2007', 'TipoB')
INSERT INTO Tabella (Id, DataLogin, TipoUtente) VALUES (3, '01/01/2007', 'TipoA')
INSERT INTO Tabella (Id, DataLogin, TipoUtente) VALUES (3, '02/01/2007', 'TipoA')
INSERT INTO Tabella (Id, DataLogin, TipoUtente) VALUES (4, '02/01/2007', 'TipoA')
INSERT INTO Tabella (Id, DataLogin, TipoUtente) VALUES (4, '03/01/2007', 'TipoA')
INSERT INTO Tabella (Id, DataLogin, TipoUtente) VALUES (5, '01/02/2007', 'TipoA')
Con la prima query vado a selezionare solo quegli utenti che hanno loggato più di una volta nel periodo di tempo scelto e che siano del tipo scelto
SELECT Id
FROM Tabella
WHERE (DataLogin BETWEEN 01/01/2007 AND 31/01/2007) AND TipoUtente='TipoA'
GROUP BY Id
HAVING (COUNT(DISTINCT [Data Login]) > 1)
E cioè mi tira fuori
Utente 1: non considerato perchè è loggato 2 volte nello stesso giorno, quindi la conta su data distinct è =1
Utente 2: non considerato perchè di TipoB
Utente 3: ok, considerato
Utente 4: ok, considerato
Utente 5: non considerato perchè ha loggato fuori dal periodo di tempo scelto
E quindi il risultato è:
3
4
Con la seconda query vorrei fare una conta di questi utenti, e dunque il risultato dovrebbe essere pari a 2
Ogni altra soluzione sullo stesso problema è ben accetta, anche se le query nidificate mi incuriosivano :P Come clausola ho che devo fare tutto tramite una sola query
Spero di essere stato chiaro, in caso contrario posso provare ad esserlo maggiormente.
Ringrazio fin d'ora per l'attenzione al problema
marcovivio
Profilo
| Expert
548
messaggi | Data Invio:
lun 12 mar 2007 - 17:39
Forse non ho capito bene il tuo problema, ma se la seguente query
>SELECT Id
>FROM Tabella
>WHERE (DataLogin BETWEEN 01/01/2007 AND 31/01/2007) AND TipoUtente='TipoA'
>GROUP BY Id
>HAVING (COUNT(DISTINCT [Data Login]) > 1)
da come risultato, come da te postato
>3
>4
Cosa ti impedisce di di far diventare la SELECT Id una SELECT count(Id)?
Io farei cosi, in questo modo il risultato che ti occorre è 2.
SELECT COUNT(Id)
FROM Tabella
WHERE (DataLogin BETWEEN 01/01/2007 AND 31/01/2007) AND TipoUtente='TipoA'
GROUP BY Id
HAVING (COUNT(DISTINCT [Data Login]) > 1)
MV
Brainkiller
Profilo
| Guru
7.999
messaggi | Data Invio:
lun 12 mar 2007 - 17:42
Prova così, (anche se fai un uso parsimonioso di subquery, ragiona magari di più sulla base dati, crea viste e join fra tabelle):
SELECT COUNT(*) FROM (
SELECT Id
FROM Tabella
WHERE (DataLogin BETWEEN 01/01/2007 AND 31/01/2007) AND TipoUtente='TipoA'
GROUP BY Id
HAVING (COUNT(DISTINCT [Data Login]) > 1)) A
Copiala e incollala per non aver problemi. La A finale è un Aliasname necessario.
Ciao
David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/
Hamelin [FL]
Profilo
| Junior Member
65
messaggi | Data Invio:
lun 12 mar 2007 - 17:54
Per marcovivio: non è possibile perchè se faccio come dici, il risultato è gruppato sugli ID, quindi non mi esce il conteggio totale, ma un numero più alto. Non posso dirti cosa esce esattamente nell'esempio perchè io lavoro su tabelle più grosse, ma ti posso dire che su una base utenti di 73 persone mi esce un risultato superiore a 1000 :) Nell'esempio riportato credo che uscirebbe 4 anzichè 2 (perchè, gruppando sull'ID, conta che è uscito 2 volte l'id 3 e 2 volte l'id 4)
Per Brainkiller: purtroppo viste non ne posso fare per vincoli particolari :( Altrimenti me la caverei subito con una query sulla prima vista... sigh.
Comunque, provando a eseguire il tuo metodo, mi restituisce il seguente errore: "Errore di sintassi o violazione di accesso"... forse c'è qualcosa da aggiustare, non saprei
marcovivio
Profilo
| Expert
548
messaggi | Data Invio:
lun 12 mar 2007 - 18:06
Non si possono fare della COUNT(DISTINCT()) come è stato fatto nella condizione di HAVING?
Scusami per prima, mi sono accorto dopo che c'era il group by che poteva dar fastidio.
Ciao ciao
MV
Brainkiller
Profilo
| Guru
7.999
messaggi | Data Invio:
lun 12 mar 2007 - 18:11
>Per Brainkiller: purtroppo viste non ne posso fare per vincoli
>particolari :( Altrimenti me la caverei subito con una query
>sulla prima vista... sigh.
>Comunque, provando a eseguire il tuo metodo, mi restituisce il
>seguente errore: "Errore di sintassi o violazione di accesso"...
>forse c'è qualcosa da aggiustare, non saprei
Tu hai postato una query no ? Immagino che funzioni quella query lì, giusto ? E stai usando SQL Server giusto ?
In ogni caso prendi la query corretta che funziona, e anteponi:
select count(*) from (
e postponi:
)a
alla tua query.
Vedari che funziona.
ciao
David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/
Hamelin [FL]
Profilo
| Junior Member
65
messaggi | Data Invio:
lun 12 mar 2007 - 18:34
La query che ho postato funziona, e sto usando SQL Server Reporting Services su SQL Server, però se antepongo e pospongo quello che mi indichi (più un "AS Expr1" che mi dà automaticamente SSRS, quindi "Select Count (*) as Expr1 from...") dà l'errore che ho indicato ^^"
Non so come mai, mi spiace ^^"
Hamelin [FL]
Profilo
| Junior Member
65
messaggi | Data Invio:
lun 12 mar 2007 - 18:56
Visto che eri sicuro dell'esattezza della risposta ho provato a modificare la query interna, che comunque da sola funziona, fino a vedere se c'era qualcosa che gli dava fastidio, e l'ho trovato: nella query interna la data è passata come parametro, quindi
WHERE (DataLogin BETWEEN @DataInizio AND @DataFine)
Purtroppo impostando il WHERE in questo modo dà questo tipo di errore. Se invece tolgo il parametro e metto la data "a mano" la query che mi hai proposto funziona... chissà come mai :-/ Purtroppo il parametro è un fattore cui non posso rinunciare, a questo punto mi sa che dovrò cercare soluzioni alternative? O qualcuno sa come se ne potrebbe venire a capo?
Per marcovivio: in effetti l'idea non mi sembrava male... ma se faccio SELECT COUNT(distinct Id) il risultato è superiore a 100... meglio dei 1000 che mi dava prima, ma comunque in qualche modo incongruente visto che gli utenti sono 73 in tutto... intanto provo a pensarci un po' per vedere se capisco cosa non va, perchè non mi sembrava male come possibilità
Hamelin [FL]
Profilo
| Junior Member
65
messaggi | Data Invio:
lun 12 mar 2007 - 19:16
Ora devo fuggire da lavoro e non posso più controllare, ma probabilmente la tua soluzione funziona
Domani ti so dire :)
Brainkiller
Profilo
| Guru
7.999
messaggi | Data Invio:
lun 12 mar 2007 - 19:21
>Ora devo fuggire da lavoro e non posso più controllare, ma probabilmente
>la tua soluzione funziona
Eh direi di sì, perchè l'ho provata.
Ma tu da dove la stai eseguendo/da dove la richiamerai ? Da un programma .NET, da un sito web, da SQL Server.
Io ti consiglio di creare una Stored Procedure, l'errore che riscontri magari è dato dal parametro che non hai valorizzato correttamente.
Ciao
David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/
Hamelin [FL]
Profilo
| Junior Member
65
messaggi | Data Invio:
mar 13 mar 2007 - 14:17
Alla fine qualche problema me lo dava ancora perchè gruppandoli mi contava tutti quelli che avevano fatto almeno una login, e non >1, non so per quale motivo ^^" Invece facendo così:
SELECT COUNT(DISTINCT Id) AS Conta, Id
FROM Tabella
WHERE (DataLogin BETWEEN 01/01/2007 AND 31/01/2007) AND TipoUtente='TipoA'
GROUP BY Id
HAVING (COUNT(Id) > 1)
Mi genera una tabella con la lista degli usrId che hanno loggato più di una volta, con l'altra colonna a 1 per tutti.
Sommando questa colonna ho il conteggio corretto
Grazie per l'indicazione che mi ha portato sulla strada giusta :)
Torna su
Stanze Forum
Elenco Threads
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 !