Newsgroup: it.comp.www.php
Titolo: Un aiuto per una query, please...

E' tutto il pomeriggio che mi sto arrovellando su una query per la
disponibilità di un appartamento in un range di date.
Le tabelle hanno i seguenti campi (per semplificare ho messo solo gli
indispensabili):
Tabella con le date riservate
app_id  date_from               date_to
1       2012-01-01      2012-01-15
1       2011-11-25      2011-12-03
1       2011-10-05      2011-10-18
1       2011-09-20      2011-09-28
2       2011-09-10      2011-09-17
3       2011-09-03      2011-09-11
1       2011-07-25      2011-08-01
1       2011-05-02      2011-05-12
1       2011-03-16      2011-03-25
1       2011-01-01      2011-01-08
la chiave esterna app_id è collegata alla tabella degli appartamenti,
quindi più appartamenti possono essere occupati nello stesso periodo.
L'utente cerca una data e dovrebbero apparire solo gli appartamenti
liberi, ma che non riesco a trovare la query giusta.
Tenete presente che non posso usare delle subquery (ho un MySQL 4).
Avrei bisogno di una query che recuperi gli app_id se le date si
accavallano, questi id poi li ripasso in un'altra query che mi recupera
gli appartamenti che non hanno quell'id.
E' macchinoso lo so, ma senza subqueries non so se è possibile farlo in
un'unica passata.
In tutti i casi non riesco a trovare una query corretta già per il primo
scopo, e, come dicevo prima, è tutto il pom. che mi ci sto
scervellando....
Ho provato con questa query:
$dateFrom = "2011-09-29";
$dateTo = "2011-10-04";
SELECT app_id 
FROM availabilities 
WHERE (date_from BETWEEN '$dateFrom' AND '$dateTo' )
OR (date_to BETWEEN '$dateFrom' AND '$dateTo')
Ma ottengo dei risultati errati...
Mi aiutereste please...?
Max
-- 
http://www.maxori.it
L'Arte è la capacità di fare cose di nessun valore
e di riuscire a venderle
F. Zappa

liberi, ma che non riesco a trovare la query giusta.
Diciamo (indicando le date con dei numeri) che hai
ID	app_id	
<1>	1	100	120
<2>	1	130	150
Se immetti un lastDate < 100, ti ritorna il record <1>. Ma se immetti
come date 115 e 125, il record <1> non matcha, ma il <2> si', e cosi'
ti risultera' che l'app_id sia libero in virtu' del record <2>. Ed e'
la situazione scomoda in cui ti trovi adesso :-)
Facciamo quindi il lavoro al contrario: vogliamo gli appartamenti che
sono OCCUPATI. Quindi firstDate < date_to AND lastDate > date_from (è
un criterio un po' poco intuitivo, questo ;-) ).
Quindi facciamo:
	SELECT tutti.* FROM
		appartamenti AS tutti
		LEFT JOIN date_riservate AS occupati
		ON (tutti.app_id = occupati.app_id 
			AND occupati.date_to > firstDate
			AND occupati.date_from < lastDate)
		WHERE occupati.app_id IS NULL;
...in questo modo selezioni tutti gli appartamenti, purche' non siano
in corrispondenza di un appartamento che ha un periodo corrispondente
occupato.
Leonardo S.E.&O.
-- 
Surstangas via akcipitr', la ceval' fojnumas nur:
Jen vigla damo en brakum', kaj vi pensas pri forkur'?
Do li turnis sin, kaj turnis sin, kaj ekdormis sen singard';
Kaj lin apudis je l' vekigx, soldatoj kaj Barnard'.

 wrote:

Grande Leonardo! Funziona benissimo!
Di dove sei? Se passo dalle tue parti ti offro una pizza, come minimo...
:)
Fra l'altro ho imparato una cosa che non conoscevo delle queries: il
fatto che nella clausola della join si potessero mettere  degli AND, non
mi era mai capitato prima nè di vederle nè di usarle. E dire che di siti
ne ho fatti...
Cmq, grazie ancora.


:)
Firenze. Sugli AND nelle JOIN, non è la stessa cosa che metterli nella
WHERE, né per quanto riguarda l'ottimizzazione della query né, e molto
più importante, per quanto riguarda i risultati: una riga che fallisce
la LEFT JOIN a causa di quell'AND sarà sempre presente nell'output, ma
con i campi impostati a NULL. Che e' il trucco usato li', appunto.
Leonardo
