Problema con query

  • Creatore Discussione Creatore Discussione Max61
  • Data di inizio Data di inizio

Max61

Utente Attivo
2 Mar 2014
760
4
18
Salve sono di nuovo qui a chiedere aiuto agli utenti del forum, ho un database di prenotazioni e una query che dovrebbe gestire i giorni egli orari liberi, dico dovrebbe perchè non fa quello che vorrei:
allego query
PHP:
$VerificaSePrenotato = "SELECT * FROM tblprenotazioneauto WHERE  str_data = '$str_data' AND
		orainizio >= '$orainizio' AND orafine <= '$orafine'
		OR orafine >= '$orainizio' AND orafine <= '$orafine'
		OR orainizio >= '$orainizio' AND orainizio <= '$orafine'
		OR orafine >= '$orainizio' AND orainizio <= '$orafine'";
praticamente questa query dovrebbe escludermi i giorni e gli orari occupati, la gestione degli orari lo fa bene, ma non tiene in considerazione il giorno, es. nel db ho questo inserimento
$str_data 20-03-2016
$orainizio 10.00
$orafine 11.00

se inserisco questo
$str_data 21-03-2016
$orainizio 10.00
$orafine 11.00
non fa inserire niente, mi dice che è già presente con lo stesso orario anche se ha il giorno diverso

se inserisco
$str_data 20-03-2016
$orainizio 12.00
$orafine 13.00

inserisce regolarmente.
Il giorno lo gestisce soltanto con questa query ...

PHP:
$VerificaSePrenotato = "SELECT * FROM tblprenotazioneauto WHERE  str_data = '$str_data'

Mi date una mano?

Grazie, Max61
 
Ciao,
Una domanda, non ti converrebbe salvare la data prenotazione e l'orario in una colonna DATETIME?
Cosi avrai la colonna inizio = "2016-03-20 10:00:00" e fine = "2016-03-20 11:00:00" e potresti gestire anche prenotazioni per più giorni.

Comunque MySql ci aiuta con l'operatore Between, quindi immaginando che le colonne orainizio e orafine siano di tipo time potremmo eseguire la seguente query:
Codice:
SELECT 
    *
FROM
    test.tblprenotazioneauto
where
    str_data = '2016-03-19'
    AND (
		time('9:00') BETWEEN orainizio AND orafine
        OR time('11:00') BETWEEN orainizio AND orafine
		)
Dove al posto di 9:00 metti l'orario di inizio e al posto di 11:00 metti quello di fine.

Dimmi se ti funziona o se qualcosa è poco chiaro.

P.S.
La tua query non funziona in quanto gli operatori logici hanno una "precedenza"... ovvero tutti gli operatori AND vengono eseguiti prima di tutti gli operatori OR (http://dev.mysql.com/doc/refman/5.7/en/operator-precedence.html)
Quindi la query da te scritta esegue prima il controllo:
Codice:
str_data = '$str_data' AND 
        orainizio >= '$orainizio' AND orafine <= '$orafine'

e poi tutti gli altri in OR quindi ti da risultati sballati, le parentesi in questo caso sarebbero tue amiche!
 
ciao Max,

la query che segue, sviluppata per MS SQL, ritorna gli automezzi disponibili in un elenco di automezzi, con prenotazioni attive

sono state usate colonne "datetime" come inizio fine

se non puoi usare le "@R_inizio" e "@R_fine", puoi sostituirle con le variabili "$" di php, rendendo il tutto compatibile con mySQL

nella query sono usate,
la tabella automezzi (anagrafica) e la tabella prenotazioni

la colonna "tipo" permette in fase di test di capire quale/i "select" hanno operato

vedi se ti è utile,
ciao
Marino

Codice:
$sql = "
declare @R_inizio	AS datetime;
declare @R_fine		AS datetime;
set @R_inizio	= '2015-11-28 05:10:00';
set @R_fine	= '2015-11-28 15:50:00';

SELECT distinct a.targa, a.descrizione, a.classe
FROM (

SELECT
  1 AS tipo
, targa
, @R_inizio	AS rich_inizio
, @R_fine	AS rich_fine
, pr_inizio
, pr_fine
  FROM prenotazioni
 WHERE @R_inizio BETWEEN pr_inizio AND pr_fine
    OR @R_fine   BETWEEN pr_inizio AND pr_fine

UNION 

SELECT
  2 AS tipo
, targa
, @R_inizio	AS rich_inizio
, @R_fine	AS rich_fine
, pr_inizio
, pr_fine
  FROM prenotazioni
 WHERE @R_inizio<pr_inizio AND @R_fine>pr_fine

) p 

right join automezzi a
on p.targa=a.targa
where p.targa is null

ORDER BY a.classe, a.descrizione;
";

il funzionamento è semplice, con la join, vengono estratte dall'anagrafica le auto che non hanno prenotazione nel giorno e negli orari indicati

(mentre le "select" interne estraggono il prenotato)
 
Ultima modifica:
Be io sto facendo una cosa molto più semplice, alla mia portata, inoltre il mezzo è soltanto 1.
Ho questi 3 campi su cui devo fare la verifica

`str_data` varchar(20) NOT NULL,
`orainizio` varchar(50) NOT NULL,
`orafine` varchar(50) NOT NULL,

Sono varchar perchè ho creato per i campi orainizio, orafine un menu a tendina dove l'utente sceglie l'orario di inizio e fine il formato è es. 10.00, 10.30, 11.00 ecc.

Quindi visto la mia inesperienza non so se riesco ad adattare il codice che mi hai postato, adesso non posso, ho da fare più tardi ci proverò.

Grazie
Max61
 
capisco Max,
quello che stai sviluppando va in crisi nel momento in cui devi gestire più automezzi
e nel caso la prenotazione fosse superiore alla giornata

creando la tabella anagrafica con 1 solo automezzo, ed adattando la query con i nomi delle tue tabelle/colonne, dovresti avere un sistema "no limits" (spero)

ti posto la query senza le "insidie"
ciao
Marino
Codice:
$sql = "

SELECT distinct a.targa, a.descrizione, a.classe
FROM (

SELECT
  1 AS tipo
, targa
, pr_inizio
, pr_fine
  FROM prenotazioni
 WHERE ".$R_inizio." BETWEEN pr_inizio AND pr_fine
    OR ".$R_fine."   BETWEEN pr_inizio AND pr_fine

UNION 

SELECT
  2 AS tipo
, targa
, pr_inizio
, pr_fine
  FROM prenotazioni
 WHERE ".$R_inizio."<pr_inizio AND ".$R_fine.">pr_fine

) p 

right join automezzi a
on p.targa=a.targa
where p.targa is null

ORDER BY a.classe, a.descrizione;
";
 
Risolto!!!
Grazie a tutti per l'aiuto, sono andato per ordine di suggerimenti, ho analizzato prima il suggerimento dell'utente f107 mettendo le parentesi nei punti giusti e questo è bastato a far si che prima di verificare gli orari verificasse il giorno.
Quindi di nuovo grazie e buon week end
Max61
 
scusa Max se riprendo il tuo post, non ho potuto farlo prima,
vorresti essere gentile e fare questo test ?
prenotazione esistente, dalle 10 alle 11
prenotazione da verificare, dalle 9 alle 12
funziona ?
ciao
Marino
 
Sì ho fatto varie prove e mi sembra tutto ok. Ho provato a fare la simulazione dalle 5.00 alle 17.00 non mi fa prenotare. Posso prenotare solo dopo le 17.01.
Ho usato la mia query iniziale agiungendo le parentesi dopo il controllo sul giorno str_data e funziona
Adesso mi è venuto un dubbio nella form di edit uso la stesa select prima dell update?
Ciao
Max61
 
Ho letto bene il tuo commento solo adesso, così come l hai impostata te non l ho provato. Adesso devo uscire tra stasera e domani lo provo e ti faccio sapere.
Grazie ancora
Max61
 
Ho verificato adesso la tua ipotesi
"prenotazione esistente, dalle 10 alle 11
prenotazione da verificare, dalle 9 alle 12"

Mi trova quella dalle 10 alle 11 e non me la salva in tabella, quindi mi sembra tutto OK.

Con calma devo provare nella form di edit se posso usare la stessa select per il controllo degli orari prima dell'update.
Appena lo faccio, ti faccio sapere
Ciao
Grazie
Max61
 
Ciao Marino51, utilizzando la procedura mi sono accorto un di problema:
nella fase di inserimento delle prenotazioni i controlli sul giorno e sugli orari con questo codice vanno bene:
PHP:
$VerificaSePrenotato = "SELECT * FROM tblprenotazioneauto WHERE  str_data = '$str_data' AND
		(orainizio >= '$orainizio' AND orafine <= '$orafine'
		OR orafine >= '$orainizio' AND orafine <= '$orafine'
		OR orainizio >= '$orainizio' AND orainizio <= '$orafine'
		OR orafine >= '$orainizio' AND orainizio <= '$orafine')";

    $query = mysql_query($VerificaSePrenotato) or die(mysql_error());

se però devo modificare un orario, utilizzando la stessa query, devo proprio cambiare gli orari altrimenti non me li fa modificare.
Es.:
orainizio= 5.30
orafine: 7.00

per esempio se volessi spostare l'orario dalle 5.30 alle 8.00, non lo posso fare perchè mi trova la prenotazione 5.30 - 7.00 e si accavalla...
Qualche idea?

Grazie
Max61
 
scusa il ritardo Max, ma fuori uso per alcuni giorni,

se nella tabella delle prenotazioni ci fosse un riferimento o contatore (tipo con incremento automatico),
dopo aver trovato il record da modificare, sarebbe molto semplice escluderlo dalla successiva ricerca,

visto che il record da modificare è "inutile", si può anche cancellare prima di fare la successiva ricerca

che dici, uno dei due metodi può andare bene ?
 
Sì c'è un id contatore quindi potrei fare una query delete e poi inserisco nuovamente il giorno e gli orari. Ci provo, grazie dell'idea. Ciao
Max61
 
Ciao Marino51, ho pensato che invece di cancellare l'intero record sarebbe meglio svuotare i campi $orainizio e $orafine, lasciando il nominativo, la data e gli altri dati, così da non rifare la prenotazione da capo.
Ho fatto questa query ma mi azzera solo il campo $orainizio di tutti i record e $orafine rimane con l'orario
PHP:
$query = 'update tblprenotazioneauto set orainizio = "" AND orafine = ""  WHERE id = "$id"';
dove sta l'errore?
Ciao
Grazie
Max61
 
PHP:
$query = "update tblprenotazioneauto set orainizio = '' AND orafine = ''  WHERE id=".$id;

vedi se puoi usare questa select, non devi cancellare o azzerare nulla
PHP:
$VerificaSePrenotato = "SELECT * FROM tblprenotazioneauto WHERE str_data = '$str_data' AND id <> $id AND 
        (orainizio >= '$orainizio' AND orafine <= '$orafine' 
        OR orafine >= '$orainizio' AND orafine <= '$orafine' 
        OR orainizio >= '$orainizio' AND orainizio <= '$orafine' 
        OR orafine >= '$orainizio' AND orainizio <= '$orafine')";
ps quest'ultima copiata da un post precedente, non controllata e solo modificata x "id"
 
Ciao Marino e grazie per l aiuto ma anche come mi hai suggerito non faceva l update sui due campi che mi interessavano, allora ho recuperato l id del record e l ho passato alla query update e sembra che funzioni.
Grazie
Buon week end
Max61
 

Discussioni simili