Dubbio "Having"
Dubbio "Having" postato il 09/07/2013 12:39:40 nel forum programmazione, open source e hosting
Signori, domanda sull'uso di "HAVING" in php.
SE ho questa stringa:
GROUP BY Nome HAVING DATE_ADD(LastPunti,INTERVAL 7 DAY)<NOW()) AS P1 ON P.Nome=P1.Nome
e vorrei aggiungere alla condizione del HAVING anche che IDRazza deve essere diverso da 5000, posso riscrivere la stringa nel seguente modo:
GROUP BY Nome HAVING (DATE_ADD(LastPunti,INTERVAL 7 DAY)<NOW()) AND IDRazza!=5000) AS P1 ON P.Nome=P1.Nome
?
Grazie a tutti :-)
Pagine → 1
09/07/2013 13:19:27
No :)
(E manca un pezzo di query :P)
La struttura di una query generica in SQL prevede che nella clausola HAVING tu abbia condizioni di selezione su un aggregatore.
Per selezionare uno specifico campo dovresti usare la clausola WHERE, esempio:
Entità PG: pgID, Nome, Razza
Entità Posts: postID, titoloPost, IDautore
Se voglio selezionare tutti i PG con più di 100 post:
SELECT pgID, COUNT(postID) AS Counter FROM PG,Posts WHERE IDautore = pgID GROUP BY pgID HAVING Counter > 100
Se dal computo voglio escludere per qualche maniera il PG 1:
SELECT pgID, COUNT(postID) AS Counter FROM PG,Posts WHERE IDautore = pgID AND pgID <> 1 GROUP BY pgID HAVING Counter > 100
09/07/2013 14:28:23 e modificato da sgc carter il 09/07/2013 14:28:59
Allora, "l'interezza" della query (che ad oggi funziona bene XD) è:
mysql_query("
UPDATE Personaggio AS P INNER JOIN (SELECT Max(DataEvento) AS LastPunti, Nome
FROM Punti
GROUP BY Nome HAVING DATE_ADD(LastPunti,INTERVAL 7 DAY)<NOW()) AS P1 ON P.Nome=P1.Nome
SET P.Explibera=P.Explibera-1
");
Ora, per mettere anche la condizione del IDRazza!=5000, la soluzione proposta da staff_universe_fairy_tail è implementabile in questo modo:
mysql_query("
UPDATE Personaggio AS P INNER JOIN (SELECT Max(DataEvento) AS LastPunti, Nome
FROM Punti
GROUP BY Nome HAVING (DATE_ADD(LastPunti,INTERVAL 7 DAY)<NOW()) && (IDRazza!=5000)) AS P1 ON P.Nome=P1.Nome
SET P.Explibera=P.Explibera-1
");
?
09/07/2013 18:40:05 e modificato da leoblacksoul il 09/07/2013 18:42:08
No! Come ha detto digital-destiny le condizioni legate a un campo non aggregato vanno necessariamente fatte con la clausola where!
Inoltre, dato che quella query l'ho scritta io XD, mi pare di ricordare che insieme a lei c'era una query gemella che faceva altro usando quelle stesse condizioni...credo che vada aggiornata anche quella allo stesso modo.
La query corretta è:
UPDATE Personaggio AS P INNER JOIN (SELECT Max(DataEvento) AS LastPunti, Nome
FROM Punti
GROUP BY Nome HAVING DATE_ADD(LastPunti,INTERVAL 7 DAY)<NOW()) AS P1 ON P.Nome=P1.Nome
SET P.Explibera=P.Explibera-1 WHERE IDRazza!=5000
09/07/2013 20:17:14
Sì, sì, c'è l'altra parte ne ho postata solo una per non appesantire il tutto, anche perché, applicare la condizione anche all'altra, poi non è un problem ^^
Vi ringrazio tutti per l'aiuto, speriamo funzioni tutto ^^
09/07/2013 20:39:51 e modificato da sgc carter il 09/07/2013 21:00:25
Ed ecco la query completa, aggiornata:
mysql_query("
UPDATE Personaggio AS P INNER JOIN (SELECT Max(DataEvento) AS LastPunti, Nome
FROM Punti
GROUP BY Nome HAVING DATE_ADD(LastPunti,INTERVAL 7 DAY)<NOW()) AS P1 ON P.Nome=P1.Nome
SET P.Explibera=P.Explibera-1 WHERE IDRazza!=5000
");
mysql_query("
INSERT INTO Punti (Nome, DataEvento, Esperienza)
(SELECT Nome, NOW(), -1 FROM
(SELECT Max(DataEvento) AS LastPunti, Nome
FROM Punti
GROUP BY Nome
HAVING DATE_ADD(LastPunti,INTERVAL 7 DAY)<NOW()) AS P1 ON P.Nome=P1.Nome WHERE IDRazza!=5000
");
Grazie a tutti!!!
09/07/2013 21:01:32
Problema... non va XD
La query postata sopra, toglie 1 punto exp a ogni PG che NON ha preso punti da una settimana MA non aggiunge la riga "Now" nella tabella Punti...
Qualche idea?
09/07/2013 21:43:17
Mi spiego meglio:
L'idea è di modificare questa query:
mysql_query("
UPDATE Personaggio AS P INNER JOIN (SELECT Max(DataEvento) AS LastPunti, Nome
FROM Punti
GROUP BY Nome HAVING DATE_ADD(LastPunti,INTERVAL 7 DAY)<NOW()) AS P1 ON P.Nome=P1.Nome
SET P.Explibera=P.Explibera-1
");
mysql_query("
INSERT INTO Punti (Nome, DataEvento, Esperienza)
(SELECT Nome, NOW(), -1 FROM
(SELECT Max(DataEvento) AS LastPunti, Nome
FROM Punti
GROUP BY Nome
HAVING DATE_ADD(LastPunti,INTERVAL 7 DAY)<NOW()) AS P1)
");
che inserisce nella tabella Punti una voce con la data "now" e sottrae un punto al PG che NON pende punti da 7 giorni
AGGIUNGENDO
una clausola che esonera tuti i PG che hanno IDRazza (nella Tabella Presenti) = 5000.
Purtroppo inserire il WHERE IDRazza!=5000 in entrambe le query (ma ho provato, anche solo in una delle due (o nell'altra) non funziona. In particolare inserendola in entrambe, il sistema NON inserisce nella tabella Punti la riga che dovrebbe inserire. QUindi viene tolto un punto al PG i questione e al riavvio della query, un altro e un altro ancora alla volta dopo ecc ecc...
Qualche idea?
10/07/2013 00:11:37
IDRazza non è una colonna di nessuna delle tabelle usate nella query di insert...quindi ovviamente la query fallisce.
Puoi farlo nella update perchè la update agisce sulla tabella Personaggio che appunto contiene il campo IDRazza
Per far funzionare anche l'insert bisogna aggiungere una tabella nelle selezioni interne. Così:
INSERT INTO Punti (Nome, DataEvento, Esperienza)
(SELECT Nome, NOW(), -1 FROM
(SELECT Max(DataEvento) AS LastPunti, Punti.Nome
FROM Punti INNER JOIN Personaggio ON Punti.Nome=Personaggio.Nome
WHERE Personaggio.IDRazza!=5000
GROUP BY Punti.Nome
HAVING DATE_ADD(LastPunti,INTERVAL 7 DAY)<NOW()) AS P1)
Visto che non bastava modificarne una per avere anche l'altra gratis? :P
10/07/2013 03:01:33
Come sempre questa community si distingue VERAMENTE da molte altre per lo spirito di collaborazione che viene dimostrato ogni volta.
Ringrazio vivamente staff_universe_fairy_tail e digital-destiny ma soprattutto leoblacksoul che già più di una volta mi ha aiutato in maniera precisa, rapida e gentilissima!
Posto il codice, qualora mai servisse a qualcun'altro:
// Malus punti
mysql_query("
UPDATE Personaggio AS P INNER JOIN (SELECT Max(DataEvento) AS LastPunti, Nome
FROM Punti
GROUP BY Nome HAVING DATE_ADD(LastPunti,INTERVAL 7 DAY)<NOW()) AS P1 ON P.Nome=P1.Nome
SET P.Explibera=P.Explibera-1 WHERE IDRazza!=5000
");
mysql_query("
INSERT INTO Punti (Nome, DataEvento, Esperienza)
(SELECT Nome, NOW(), -1 FROM
(SELECT Max(DataEvento) AS LastPunti, Punti.Nome
FROM Punti INNER JOIN Personaggio ON Punti.Nome=Personaggio.Nome
WHERE Personaggio.IDRazza!=5000
GROUP BY Punti.Nome
HAVING DATE_ADD(LastPunti,INTERVAL 7 DAY)<NOW()) AS P1)
");
Grazie a tutti!
Discussione seguita da
Pagine → 1
Rispondi alla Discussione Segui Discussione Inoltra Discussione Forum Programmazione, Open Source e Hosting Elenco Forum
Articoli, Interviste e altre Risorse!
State of Survival ↗
Raja Dunia ↗
Exclusive Villa GdR ↗
Storie di Agarthi ↗
Enlisted ↗
The Coven ↗
Project Entropy ↗
World of Warship ↗
New Orleans ↗