Estrazione errata

giovedì 05 maggio 2011 - 22.49

dupperelko Profilo | Junior Member

Ciao a tutti,
ho un problema con una estrazione...

se ho una tabella anagrafica fatta così:
cod nome rappresentante_di_zona citta
001 rossi 06 milano
002 verdi 04 milano
003 bianchi 08 torino
004 neri 04 genova
005 carlo 05 como
006 gianni 05 novara
007 marco 04 novara
008 lorenzo 04 milano
009 antonio 06 torino

e una tabella ordini così:
cod numero campo4 data
001 45656 jg 30/04/1975
001 6634 kik76uy 30/04/1975
001 2354 iyu 30/04/1978
002 976 yujkuty 30/04/1978
002 898786 jujyt 30/04/1978
003 5465 oiu 30/04/1975
003 5988 8ujy 30/04/1978
003 2342 iujy 30/04/1978
004 67675 ujy 30/04/1975
004 45656 jgg 30/04/1975
005 6634 kik76uyg 30/04/1975
006 2354 iyuh 30/04/1978
007 976 yujkutyggh 30/04/1978
004 898786 jujytg 30/04/1975
004 5465 oiu 30/04/1975
005 5988 8ujyhg 30/04/1978
008 2342 iujy 30/04/1975
004 67675 ujy 30/04/1975

vorrei fare un'estrazione che mi dica (passando un cod rappresentante e la data che sia <> da 30/04/1978):
l'elenco dei paesi e quanti clienti (di quel rappresentante) ci sono in ogni paese...
esempio.. se passo 04 avrò:
citta numero
genova 1
milano 1
in pratica ho contato i clienti di 04 guardando però che, negli ordini, la data si <> da quella passata.

Ho provato a fare questo:

SELECT AN.citta, Count(*) AS numero
FROM anagrafica AS AN INNER JOIN ordini AS MS ON AN.cod = MS.cod
WHERE (((AN.rappresentante_di_zona)=[?]) AND ((MS.data)<>'30/04/1978'))
GROUP BY AN.citta;


però non va... perché mi conta tutti i dettagli degli ordini... in pratica se passo 04 ottengo:

genova 5
milano 1

dove 5 (elenco ordini del cliente 004) è sbagliato.. perché a genova, il rappr 04, ha solo un cliente (lo 004) e non 5...

Come faccio a fare il distinct?
o altro?
grazie in anticipo

lbenaglia Profilo | Guru

>ho un problema con una estrazione...

Ciao,

Qual è la PK della tabella Ordini? A prima vista sembrerebbe il numero ma esistono valori duplicati...
Con che DBMS lavori?

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/

dupperelko Profilo | Junior Member

Ciao Lorenzo,
no.. non ho chiavi..

l'unica join è il cod, che in anagrafica è univoco e in ordini può essere replicato (perché uno user può fare più ordini)..

in pratica io voglio sapere quanti clienti ha ogni rappresentante (ma il cliente non deve essere contato se ha la data 30/04/1978 negli ordini)
raggruppati per paese:
quindi

milano 15
torino 14

e così via


grazie

ciao

lbenaglia Profilo | Guru

>Ciao Lorenzo,
>no.. non ho chiavi..
Questo è un male dato che non viene rispettata nemmeno la prima forma normale (1NF).

>in pratica io voglio sapere quanti clienti ha ogni rappresentante
>(ma il cliente non deve essere contato se ha la data 30/04/1978
>negli ordini)
>raggruppati per paese:
Nella tabella Ordini quale colonna rappresenta "il cliente"?
E ribadisco, quale DBMS utilizzi?

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/

dupperelko Profilo | Junior Member

>>Ciao Lorenzo,
>>no.. non ho chiavi..
>Questo è un male dato che non viene rispettata nemmeno la prima
>forma normale (1NF).
>
>>in pratica io voglio sapere quanti clienti ha ogni rappresentante
>>(ma il cliente non deve essere contato se ha la data 30/04/1978
>>negli ordini)
>>raggruppati per paese:
>Nella tabella Ordini quale colonna rappresenta "il cliente"?

cod...
come vedi in ana è univoco.. e in ordini è ripetuto

>E ribadisco, quale DBMS utilizzi?

scusami mi è sfuggita la domanda... uso access

>
>Ciao!
>--

grazie


>Lorenzo Benaglia
>Microsoft MVP - SQL Server
>http://blogs.dotnethell.it/lorenzo/

lbenaglia Profilo | Guru

> come vedi in ana è univoco.. e in ordini è ripetuto
Ad essere sincero non ho capito cosa sia il rappresentante ed il cliente...
Con i dati che hai postato quale deve essere il result set desiderato (preciso, non a spanne)?

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/

dupperelko Profilo | Junior Member

allora mettiamola così...
tanto a rifare le tabelle non ci vuole niente...

io ho dei rappresentanti che devo mandare in giro da vari clienti...
quindi in tabella anagrafica associo un rappresentante (che qui indico con un numero) per ogni cliente.

tabella anagrafica
codcliente nomecliente rappresentante citta
1 rossi 004 milano
2 verdi 004 milano
3 bianchi 003 milano
4 gialli 004 torino

tabella ordini
idordine codcliente data
1000 1 06/05/2011
1001 1 06/05/2011
1002 1 06/05/2011
1003 2 null
1004 2 null
1005 3 06/05/2011
1006 3 06/05/2011
1007 4 06/05/2011


pk anagrafica: codcliente
pk ordini: idordine

io voglio sapere quanti clienti, raggruppati in numero per ogni città, ha ogni rappresentante (ma con data non null)...
esempio: per rappresentante 004 avrò a milano un cliente (verdi non lo conta perché data null)
e a torino uno...
quindi

voglio un set dati (per 004) così:
milano 1
torino 1

e se passo, invece, rapp 003 avrò:
milano 1


grazie per la disponibilità

ciao

lbenaglia Profilo | Guru

>allora mettiamola così...
>tanto a rifare le tabelle non ci vuole niente...

Ti allego uno script in T-SQL per SQL Server anche se il secondo esempio è pienamente compatibile con Access:

USE tempdb; CREATE TABLE dbo.Anagrafiche( codcliente int NOT NULL PRIMARY KEY, nomecliente varchar(10) NOT NULL, rappresentante char(3) NOT NULL, citta varchar(10) NOT NULL ); CREATE TABLE dbo.Ordini( idordine int NOT NULL PRIMARY KEY, codcliente int NOT NULL, data date NULL, CONSTRAINT FK_Ordini_Anagrafiche FOREIGN KEY(codcliente) REFERENCES dbo.Anagrafiche(codcliente) ); INSERT dbo.Anagrafiche VALUES (1, 'rossi', '004', 'milano') , (2, 'verdi', '004', 'milano') , (3, 'bianchi', '003', 'milano') , (4, 'gialli', '004', 'torino'); INSERT dbo.Ordini VALUES (1000, 1, '20110506') , (1001, 1, '20110506') , (1002, 1, '20110506') , (1003, 2, NULL) , (1004, 2, NULL) , (1005, 3, '20110506') , (1006, 3, '20110506') , (1007, 4, '20110506'); GO /* Soluzione per SQL Server */ CREATE PROCEDURE dbo.up_ClientiPerCittà @rappresentante char(3) AS SELECT A.citta, COUNT(DISTINCT A.nomecliente) AS cliente FROM dbo.Anagrafiche AS A INNER JOIN dbo.Ordini AS O ON A.codcliente = O.codcliente WHERE A.rappresentante = @rappresentante AND O.data IS NOT NULL GROUP BY A.citta; GO EXEC dbo.up_ClientiPerCittà '004'; /* Output: citta cliente ---------- ----------- milano 1 torino 1 (2 row(s) affected) */ EXEC dbo.up_ClientiPerCittà '003'; /* Output: citta cliente ---------- ----------- milano 1 (1 row(s) affected) */ /* Soluzione compatibile con Access */ SELECT A.citta, COUNT(*) AS cliente FROM Anagrafiche AS A INNER JOIN ( SELECT codcliente FROM Ordini WHERE data IS NOT NULL GROUP BY codcliente ) AS O ON A.codcliente = O.codcliente WHERE A.rappresentante = '004' GROUP BY A.citta; /* Output: citta cliente ---------- ----------- milano 1 torino 1 (2 row(s) affected) */ SELECT A.citta, COUNT(*) AS cliente FROM Anagrafiche AS A INNER JOIN ( SELECT codcliente FROM Ordini WHERE data IS NOT NULL GROUP BY codcliente ) AS O ON A.codcliente = O.codcliente WHERE A.rappresentante = '003' GROUP BY A.citta; /* Output: citta cliente ---------- ----------- milano 1 (1 row(s) affected) */ DROP PROCEDURE dbo.up_ClientiPerCittà; DROP TABLE dbo.Ordini, dbo.Anagrafiche;

La SELECT del secondo esempio puoi incapsularla in una Query parametrica.

>grazie per la disponibilità
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/

dupperelko Profilo | Junior Member

Perfetto... mi mancava quel pezzo.. ora ho capito...

grazie per il tempo dedicato...


alla prox

ciao



d.

dupperelko Profilo | Junior Member

Ciao,
ancora un consiglio per favore.

Se adesso volessi rendere linkabile il resultset (e questo del linkabile l'ho fatto)
in modo che, al click, vada su un'altra pagina per un report completo diviso per ogni cliente..
quindi cliccando, per esempio, su "genova 4" avrò:
_____________________________________________
codcliente nomecliente rappresentante città data
150 carlo 12 genova 16/05/2011

elenco degli ordini
1010
1011
1012
_____________________________________________
codcliente nomecliente rappresentante città data
151 carlotta 12 genova 17/05/2011

elenco degli ordini
1013
1014
1015
1016
_____________________________________________
codcliente nomecliente rappresentante città data
152 carlone 12 genova 18/05/2011

elenco degli ordini
1017
_____________________________________________
codcliente nomecliente rappresentante città data
153 carlino 12 genova 19/05/2011

elenco degli ordini
1018
1019
_____________________________________________


che procedura dovrei seguire per avere un risultato del genere?
Sarebbe una doppia select nidificata di cui una ciclata, visti ordini multipli... in che modo è possibile una cosa del genere?

a lato codice pagina (vb.net) non dovrei avere problemi... ma a livello di codice sql come devo comportarmi?
naturalmente devo rispettare il vincolo iniziale: in cui avevo scelto un rappresentante e una data non null..
per questo sul report ho lo stesso rappresentante e date non null....

attendo consigli..

e grazie in anticipo

dupperelko Profilo | Junior Member

Risolto... più facile a dire che a fare... ho proprio fatto quello che chiedevo..
in pratica ho eseguito una select
ciclata

Dr = Cmd.ExecuteReader
Do While Dr.Read
...............

e poi per ogni record ho eseguito un'altra select... ulteriormente ciclata..
ci ho messo un po a capirlo ma funziona... :)
grazie

ciao

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-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5