-
JOIN temporale
Ciao a tutti.
Avrei la necessità di fare un controllo relativo agli ordini di uno specifico utente prendendo come valori di riferimento 3 campi settati con datetime.
Nello specifico ho:
Nome tabella: prenotazione
Campo: id_prodotto, ora_prenotazione, user
Nome tabella: prodotto
Campi: id_prodotto, date_start e date_end
Ciò che dovrei fare è estrapolare l'ultimo id_prodotto di user (in ordine decrescente) della tabella prenotazione e vedere se la sua ora_prenotazione sia > a date_start e < a date_end della tabella prodotto.
Che tipo di SELECT dovrei fare? Una JOIN?
-
Supponendo che user sia l'utente connesso (giusto?) una soluzione potrebbe essere:
Codice PHP:
SELECT * FROM prenotazione
LEFT JOIN prodotto ON prodotto.id_prodotto = prenotazione.id_prodotto
WHERE (SELECT max(prenotazione.id_prodotto)
FROM prenotazione WHERE user = $login)
&& prenotazione.ora_prenotazione > prodotto.date_start && prenotazione.ora_prenotazione < prodotto.date_end;
Mi affido però a chi ne saprà sicuramente più di me
-
Sì, per l'user utilizzo la $_SESSION['login'], perché l'utente che deve vederlo
Ho provato il tuo codice, però non funziona :(
-
Deve adattare alla sintassi che usa il suo script php. Indubbiamente qualcosa deve restituire (impossibile non funziona nel senso nessuno output).
Left Join in breve restituisce i campi della tabella di sinistra e se non vero il valore è null.
Con la funzione fetch_assoc ad esempio gli elementi sono i nomi dei campi dalla variabile array creata.
Codice PHP:
<?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
$query = "SELECT Name, CountryCode FROM City ORDER BY ID DESC";
$result = $mysqli->query($query);
/* fetch associative array */
while ($row = $result->fetch_assoc()) {
printf("%s (%s)\n", $row["Name"], $row["CountryCode"]);
}
?>
Se lei utilizza tale funzione e con la variabile $row avrà anche $row['id_prodotto'] e così via (la tabella di sinistra è prenotazione come la sintassi SQL gentilmente creata e fornita da crystaltokyo https://forum.it.altervista.org/php-...ml ovviamente sostituisci $login con $_SESSION['login'])
Concatenazione stringa php.
Se con apice singolo:
Codice PHP:
$var = 'Ciao $_SESSION[\'login\']';
$concatenazione = $var . ' Mondo';
var_dump($concatenazione); // Output Ciao $_SESSION['login'] Mondo
o prima o dopo il punto concatena stringa o variabile con valori scalari che possono essere rappresentati in stringa.
Risultato finale:
Codice PHP:
$query = 'SELECT * FROM prenotazione
LEFT JOIN prodotto ON prodotto.id_prodotto = prenotazione.id_prodotto
WHERE (SELECT max(prenotazione.id_prodotto)
FROM prenotazione WHERE user = '. $_SESSION['login'] . ')
&& prenotazione.ora_prenotazione > prodotto.date_start && prenotazione.ora_prenotazione < prodotto.date_end;';
-
Sì, avevo sbagliato perché avevo omesso i due apici, dunque mi dava errore.
Ne aproffitto per fare un'ultima domanda, il cui processo è simile ma con tabelle diverse.
Sempre con due tabelle, così formate:
Tabella 1: chat
id |
mittente |
id_chat |
ora (datetime) |
tipo |
Tabella 1: chat_on
id_chat |
user |
date_start (datetime) |
date_end (datetime) |
Posto qui di seguito il codice e poi il semplice errore che mi dà:
Codice PHP:
//vedo se è una chat è attiva oppure no (funziona!)
$check = gdrcd_query("SELECT * FROM chat_on WHERE id_chat = ".$_SESSION['luogo']."", 'result');
if(gdrcd_query($check, 'num_rows') > 0) {
//c'è una chat attiva
//Passaggio 1.1: Seleziono l'ultimo id di chat.mittente e, se il nome è diverso da chat_on.user, verifico che chat.tipo=P e chat.ora sia > chat_on.date_start MA chat.ora < chat_on.date_end.
$info = gdrcd_query("SELECT * FROM chat
LEFT JOIN chat_on ON chat_on.id_chat = chat.id_chat
WHERE (SELECT max(chat.id)
FROM chat WHERE chat_on.id_chat = chat.id_chat)
&& chat.ora > chat_on.date_start && chat.ora < chat_on.date_end && chat.mittente != chat_on.user && chat.tipo='P'", 'result');
//passaggio 1.1: oltre questo, verifico se NOW() abbia superato l'ora di chat_on.date_end. Se il tempo è scaduto, dunque NOW() è superiore a date_end, blocco qualsiasi azione:
$check_ora = gdrcd_query("SELECT * FROM chat_on WHERE luogo = ".$_SESSION['luogo']."");
//valorizzo
if ((gdrcd_query($info, 'num_rows') < 1) && ($check_ora['date_end'] < 'NOW()')) {
//non c'è neanche risultato, ma il tempo è scaduto e dunque non si può scrivere
} else if ((gdrcd_query($info, 'num_rows') > 0) && ($check_ora['date_end'] > 'NOW()')) {
//C'è un risultato tra date_start e date_end
} else {
//non c'è nessun risultato, il date_end non è scaduto e per questo si può scrivere
}
} else {
//non c'è nessuna chat attiva
}
Il codice posto così funziona, salvo in una cosa.
Se io che sono online sono != da chat_on.user, il primo if mi viene riconosciuto (non c'è neanche risultato, ma il tempo è scaduto e dunque non si può scrivere), ma il secondo e il terzo no.
Quindi se ci sono le condizioni per cui O "C'è un risultato tra date_start e date_end" O "non c'è nessun risultato, il date_end non è scaduto e per questo si può scrivere", come risultato mi dà sempre il primo (non c'è neanche risultato, ma il tempo è scaduto e dunque non si può scrivere).
Sapete come mai e dove sbaglio?
Non so se ho reso il concetto.
-
Codice PHP:
$query = 'SELECT * FROM prenotazione
LEFT JOIN prodotto ON prodotto.id_prodotto = prenotazione.id_prodotto
WHERE (SELECT max(prenotazione.id_prodotto)
FROM prenotazione WHERE user = '. $_SESSION['login'] . ')
&& prenotazione.ora_prenotazione > prodotto.date_start && prenotazione.ora_prenotazione < prodotto.date_end;';
Simile alla precedente ma le tabelle e i campi hanno nomi differenti.
Se id_chat è diverso per utente a che serve verificare l'uguaglianza? Inoltre è uguale implicitamente a id_chat se tabella chat_on campo user con tabella chat campo mittente. Invece tabella chat_on campo date_start e tabella chat_on campo date_end si riferiscono al prodotto se tabella chat campo tipo e valore P?
Codice PHP:
$query = 'SELECT * FROM chat
LEFT JOIN chat_on ON chat_on.id_chat = chat.id_chat
WHERE (SELECT max(chat.id_chat)
FROM chat WHERE mittente = \''. $_SESSION['login'] . '\')
&& chat.tipo = \'P\'
&& chat.ora > chat_on.date_start && chat.ora < chat_on.date_end;';
In realtà crei la tabella prodotto con i dati, poi l'utente effetua la prenotazione previa verifica che il tempo è valido e solo dopo lo memorizzi dentro al database, Non dovrebbe esistere user con id_prodotto dentro la tabella prenotazione se il tempo non è valido (quella validazione ti serve appunto per inserirlo nella tabella prenotazione). Te lo mostro come una domanda, id_prodotto uguale 1 e user domenico quante volte è presente nella tabella prenotazione? Da nessuna a almeno una volta per il prodotto 1 (poiché la struttura dei campi sono: id_prodotto, ora_prenotazione e user è specifica del id_prodotto 1 e user domenico, non una prenotazione generica o comunque non possiedi altri dati utili in quella tabella prenotazione) se fa due ordini a più tempi ovviamente da almeno una volta diventa a due volte per il prodotto id 1 e user domenico (che comunque previa validazione uno a uno) sono due ordini validi.
Quindi previa validazione se è loggato crei DateTime in php
Codice PHP:
<?php
session_start();
if(empty($_SESSION['login'])) {
// Inserire codice redirect al login
} else {
$prodotto = '1234';
$timezone = new \DateTimeZone('Europe/Rome');
$date1 = new \DateTime('now', $timezone);
$format1 = $date1->format('Y-m-d H:i:s.u');
$query = 'Select * FROM prodotto WHERE id_prodotto = ' . $prodotto . ';';
$variabile_contenitore = gdrcd_query($query, 'result');
$date2 = new \DateTime($variabile_contenitore['date_start'], $timezone);
$date2 = new \DateTime($variabile_contenitore['date_end'], $timezone);
if($date1 >= $date2 && $date1 <= $date3) {
// Istruzione SQL per inserimento id_prodotto, ergo memorizzare id_prodotto 1234 e user dentro la tabella prenotazione
}
}
?>
Se poi gentilmente chiarisci cosa significa la tabella chat_on, quasi certamente ti indico come modificare la struttura