Condizioni HAVING
Condizioni HAVING postato il 21/05/2017 21:49:33 nel forum programmazione, open source e hosting
Buonasera,
rieccomi qui, ancora una volta a cercare l'illuminazione XD
Il problema di oggi sembra veramente banale, ma mi sta facendo impazzire.. magari sbaglio una cavolata ma... tutto a suo tempo:
Da anni usiamo il seguente codice:
mysql_query("
UPDATE Personaggio AS P INNER JOIN (SELECT Max(DataEvento) AS LastPunti, Nome
FROM Punti
GROUP BY Nome HAVING DATE_ADD(LastPunti,INTERVAL 90 DAY)<NOW()) AS P1 ON P.Nome=P1.Nome
Set IDRazza = 5000");
Per impostare la Razza del PG intattivo da 90 giorni alla "Razza Inattiva".
Funziona bene, ma ora volevo modificare il sistema per permettere "diverse Razze inattive".
L'idea sarebbe avere una razza inattiva dopo 30 giorni, una dopo 60 e una dopo 90 (serve per l'organizzazione interna dei ruoli e per evitare che PG inattivi da tot tempo, blocchino cariche imp...)
Illudendomi che fosse "facile" ho scritto:
mysql_query("
UPDATE Personaggio AS P INNER JOIN (SELECT Max(DataEvento) AS LastPunti, Nome
FROM Punti
GROUP BY Nome HAVING DATE_ADD(LastPunti,INTERVAL 30 DAY)<NOW()) AS P1 ON P.Nome=P1.Nome
Set IDRazza = 5000");
mysql_query("
UPDATE Personaggio AS P INNER JOIN (SELECT Max(DataEvento) AS LastPunti, Nome
FROM Punti
GROUP BY Nome HAVING DATE_ADD(LastPunti,INTERVAL 60 DAY)<NOW()) AS P1 ON P.Nome=P1.Nome
Set IDRazza = 6000");
mysql_query("
UPDATE Personaggio AS P INNER JOIN (SELECT Max(DataEvento) AS LastPunti, Nome
FROM Punti
GROUP BY Nome HAVING DATE_ADD(LastPunti,INTERVAL 90 DAY)<NOW()) AS P1 ON P.Nome=P1.Nome
Set IDRazza = 7000");
ma ovviamente il problema è che le condizioni si verificano "a catena" quindi il PG inattivo da 90 giorni lo è anche da 60 e da 30.
Allora ho pensato, metto un HAVING con due condizioni:
mysql_query("
UPDATE Personaggio AS P INNER JOIN (SELECT Max(DataEvento) AS LastPunti, Nome
FROM Punti
GROUP BY Nome HAVING (DATE_ADD(LastPunti,INTERVAL 30 DAY)<NOW()) AND DATE_ADD(LastPunti,INTERVAL 60 DAY)>NOW()) )AS P1 ON P.Nome=P1.Nome
Set IDRazza = 5000");
mysql_query("
UPDATE Personaggio AS P INNER JOIN (SELECT Max(DataEvento) AS LastPunti, Nome
FROM Punti
GROUP BY Nome HAVING (DATE_ADD(LastPunti,INTERVAL 60 DAY)<NOW()) AND DATE_ADD(LastPunti,INTERVAL 90 DAY)>NOW()))AS P1 ON P.Nome=P1.Nome
Set IDRazza = 6000");
mysql_query("
UPDATE Personaggio AS P INNER JOIN (SELECT Max(DataEvento) AS LastPunti, Nome
FROM Punti
GROUP BY Nome HAVING DATE_ADD(LastPunti,INTERVAL 90 DAY)<NOW()) AS P1 ON P.Nome=P1.Nome
Set IDRazza = 7000");
Ma anche qui, niente da fare...
Ora mi viene il dubbio sulle condizioni imponibili al HAVING e soprattutto se ho scritto bene tutto il resto... ovviamente non funziona, quindi qualcosa di errato c'è ma non riesco a venirne a capo :(
Qualsiasi aiuto o consiglio sarebbe molto ben accetto ^^
Grazie
Pagine → 1
21/05/2017 23:07:38 e modificato da rematore il 21/05/2017 23:08:53
Ciao,
ciò che chiedi tutto, secondo la mia logica, può essere
implementato usando soltanto due query e una condizione if.
La prima si occuperà di prelevare il valore legato all'attributo che chiami "lastPunti".
La condizione if esegue lo switch in base ai giorni ed esegue l'update dell'attributo IDRazza in base al quantitativo di giorni.
Tutta la logica legata alla differenza tra le date
è lasciata alla funzione date_diff
<?php
#data attuale (formato db)
$oggi = date('Y-m-d H:i:s', strtotime('now'));
#.. query ed esecuzione per prelevare il valore lastPunti.
$ls = $row['lastPunti'];
#calcolo la differenza di giorni tra la data attuale e l'ultima registra
$d = date_diff($oggi, $ls);
$d = (int) $d->format('%a');
if ($d > 0 && $d <= 30) {
$id_razza_inattiva = 5000;
} else if ($d > 30 && $d <= 60) {
$id_razza_inattiva = 6000;
} else if ($d > 60 && $d <= 90) {
$id_razza_inattiva = 7000;
} else {
die('errore');
}
mysql_query("
UPDATE Personaggio AS P INNER JOIN (SELECT Max(DataEvento) AS LastPunti, Nome
FROM Punti) AS P1 ON P.Nome=P1.Nome
Set IDRazza = " . $id_razza_inattiva . " ");
Attenzione, il codice che ho scritto è un esempio di possibile logica. Il codice non implementa bind di eventuali parametri per la query. È consigliato farlo, come è consigliato passare almeno a mysqli per una migliorare sicurezza.
22/05/2017 00:20:44
Hmm, speravo veramente di riuscire finalmente a capire questo HAVING così elusivo..ma intanto proverò con la soluzione da te proposta.
Grazie :-)
22/05/2017 06:05:18
OK, sono leggermente stanco e devo assolutamente andare a dormire (XD) ma prima che altri si scervellino per rispondermi "inutilmente", ci tenevo a postare come ho "risolto" il problema...
A dire il vero non sono certo cosa sia diverso dalle mille iterazioni che ho provato... ma fatto sta che funziona quindi, domani... anzi, dopo a mente fresca vedrò di capire meglio ma intanto funziona :-)
Ecco, se mai servisse ad altri, il codice:
mysql_query("
UPDATE Personaggio AS P INNER JOIN (SELECT Max(DataEvento) AS LastPunti, Nome
FROM Punti
GROUP BY Nome HAVING
DATE_ADD(LastPunti,INTERVAL 30 DAY)<NOW())
AS P1 ON P.Nome=P1.Nome
Set IDRazza = '3000'");
mysql_query("
UPDATE Personaggio AS P INNER JOIN (SELECT Max(DataEvento) AS LastPunti, Nome
FROM Punti
GROUP BY Nome HAVING
DATE_ADD(LastPunti,INTERVAL 60 DAY)<NOW())
AS P1 ON P.Nome=P1.Nome
Set IDRazza = '6000'");
mysql_query("
UPDATE Personaggio AS P INNER JOIN (SELECT Max(DataEvento) AS LastPunti, Nome
FROM Punti
GROUP BY Nome HAVING
DATE_ADD(LastPunti,INTERVAL 90 DAY)<NOW())
AS P1 ON P.Nome=P1.Nome
Set IDRazza = '9000'");
Pagine → 1
Rispondi alla Discussione Segui Discussione Inoltra Discussione Forum Programmazione, Open Source e Hosting Elenco Forum
Articoli, Interviste e altre Risorse!
Exclusive Villa GdR ↗
Tibia ↗
World of the Sea Battle ↗