Select sql + join, risultato record duplicati

venerdì 17 settembre 2010 - 10.18

trinity Profilo | Guru

Buongiorni a tutti,

ragazzi ho questo problema ossia ho creato una query di selezione al cui interno gli passo due date di confronto, questa query costituita da alcune join ma il risultato che mi esce non è quello che desidero. ora vi posto le tabella e successivamente vi spiego meglio cos ami serve:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra


in pratica devo eseguire una select con delle join in cui se passo alla query un periodo di controllo tipo maggio(01/05/2010 - 31/05/2010) deve vedere se ci sono notifiche in quel periodo per ogni albergo, ovviamente l'esempio è per un solo albergo, e prendere il totale dei letti

ciò vuole dire che stando ai dati che ho passato deve uscire come record l'albergo1 che ha 45 nrletto, io ho fatto così la query :


SELECT Alb.Codcategoria, Sum(An.nrletti) AS Letti
FROM Albergo AS Alb
INNER JOIN
Anagrafica_camere AS An
ON Alb.Codalb = An.codalbergo AND Alb.CodComune = An.codcomune
INNER JOIN
Notifiche AS Ntf
ON Alb.Codalb = Ntf.codalbergo AND Alb.CodComune = Ntf.codcomune
WHERE Ntf.data BETWEEN '20100501' AND '20100531'
GROUP BY Alb.CodComune,Alb.Codcategoria
ma ovviamente mi sono reso conto che così la query prendere e somma tutti i letti dell'abergo1 per il numero di record presenti nella tabella notifica visto che ce ne sono nel periodo di maggio. Come faccio ad evitare di raddoppiare i record dei letti?


Ciao e grazie
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

boccia75 Profilo | Junior Member

Ciao,
nella struttura della tabella ALBERGO che hai postato non ho trovato il campo CODCATEGORIA (che tu estri nella query di esempio).
Questa è la mia soluzione:
SELECT Sum(An.nrletti) AS Letti,an.codalbergo
FROM anagrafica_camere as an
where an.codalbergo in (select a.Codalb from
albergo as A,notifiche as B
where a.codalb=b.codalbergo
and a.codcomune=b.codcomune
and b.data between '20100501' AND '20100531'
and a.codalb=an.codalbergo
and a.codcomune=an.codcomune)
group by an.codalbergo

Risultato della query
NRLETTI = 45
CODALBERGO = 1


CIAO!

trinity Profilo | Guru

Funziona perfettamente, ma ora mi è successo un caso in cui al codice che mi hai postato dovrei aggiungere un'ulteriore tabella ossia la tabella "Movimenti" ossia se la struttura ha inserito dei movimenti allora deve essere conteggiata nel calcolo dei letti altrimenti no

ti posto la tabella con vari insert:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra


calcola che le date di partenza potrebbero non essere state create in quanto non c'è effettivamente la partenza pertanto il campo è Null oppure possono esserci casi in cui arrivi a maggio e parti a giugno, cmq in entrambi i casi se ci sono devono essere contati per il calcolo dei letti.

Ciao e grazie mille
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

boccia75 Profilo | Junior Member

Ciao,
non ho capito molto bene quello che vuoi ottenere....oltre al controllo sulla data presente in notifica vuoi aggiungere anche il controllo se ci sono o meno movimenti?
Mi puoi postare un esempio con il risultato che vorresti ottenre?
Ciao!

trinity Profilo | Guru

In pratica come ti avevo posta nella prima sezione, noi siamo andati a fare un controllo sulle notifiche, se rientravano nella data di maggio allora andavamo ad ottenere la somma dei letti della struttura 1, a questo controllo si deve aggiungere quello sui movimenti perchè mi può capitare che non ci siano notifiche ma che cmq la struttura ha inserito dei movimenti, pertanto se questa struttura avesse inserito anche un solo movimento devo prenderla come aperta e quindi calcolare la somma dei letti...ti faccio capire meglio ecco i casi un cui deve essere presa la struttura:

1) caso in cui dataarrivo=05/05/2010 e datapartenza=10/05/2010
2) caso in cui dataarrivo=25/04/2010 e datapartenza=10/05/2010
3) caso in cui dataarrivo=25/05/2010 e datapartenza=10/06/2010
4) caso in cui dataarrivo=25/05/2010 e datapartenza=Null (in questo caso il cliente all'interno della struttura non è partito ma è arrivato nel mese di riferimento)
5) caso in cui dataarrivo=25/04/2010 e datapartenza=10/06/2010 (in questo caso il clienti è arrivato ad aprile e non a maggio ma è partito a giugno quindi cmq ha fatto la presenza nel mese di maggio e pertanto deve essere preso)

Ovviamente come nel quesito delle notifiche il calcolo dei letti deve essere eseguito una sola volta quindi uscire:

Risultato della query
NRLETTI = 45
CODALBERGO = 1


Ciao
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

boccia75 Profilo | Junior Member

Ciao,
premetto che ancora non ho ben capito cosa vuoi ottenere (o meglio, nella prima condizione mettiamo che la data sia compresa nell'intervallo che tu vai ad indicare,nella tabella movimenti, visto che ci sono due date, non saprei bene che condizione inserire).
Io ho pensato che tu volessi controllare SE la data NOTIFICHE è compresa nelle date di riferimento O SE la data di arrivo è maggiore uguale della minore data di riferimento (scusa il gioco di parole) OPPURE se la data di partenza è minore uguale della maggiore data di riferimento, corretto?
Se è questo che stai cercando la soluzione potrebbe essere questa.
Ho impostato una condizione sulla data di partenza (visto che potrebbe essere null) e quindi ho inserito la condizione isnull(datapartenza,getdate()), in questo modo ricevo un valore di data che sarà la data odierna del lancio della query(se la data di partenza è null significa che è ancora in albergo, no?)


La query che ti propongo è questa:

SELECT Sum(An.nrletti) AS Letti,an.codalbergo
FROM anagrafica_camere as an
where an.codalbergo in (select a.Codalb from
albergo as A,notifiche as B,movimenti as c
where a.codalb=b.codalbergo
and a.codcomune=b.codcomune
and a.codalb=c.codalbergo
and a.codcomune=c.codcomune
and (b.data between '20100501' AND '20100531'
OR (c.dataarrivo>='20100501' or isnull(c.datapartenza,getdate())<='20100531'))
and a.codalb=an.codalbergo
and a.codcomune=an.codcomune)
group by an.codalbergo


Mi sembra che funzioni, se ho capito bene le tue necessità.
Ciao!

trinity Profilo | Guru

Funziona ma in parte...
il discorso è che le situazioni che incontro per gestire bene la where sono diverse, ti dovrei spiegare bene tutto, se ti va ti scrivo tutto per bene e così potrai meglio capire cosa devo ottenere dalla query

boccia75 Profilo | Junior Member

Non c'è problema, se non hai troppa fretta.......invia pure.
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-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5