- Home
- Categorie
- Coding e Sistemistica
- MYSQL e altri Database
- Mysql - record trovato piu volte
-
Ah scusa avevo capito male ciò che chiedevi, prova cosi:
SELECT * FROM tabella GROUP BY id HAVING count(id) = (SELECT count(id) AS n_trovati FROM tabella GROUP BY id ORDER BY n_trovati DESC LIMIT 1)
-
Funziona:D... grazie...
Tanto per capire se ho capito...
la prima query come prima grazie ad having va a vedere quante righe ci sono in ogni gruppo
La seconda salva in n_trovati gli id che count conta sempre suddividendoli in gruppi. Con order by n_trovati desc limit 1 li ordina in ordine decrescente e seleziona solo l'ultimo che inevitabilmente è il più grande
Mettendole assieme le due e usando la seconda come parametro delle query having, seleziono l'id trovato in più righe, che è quello che a me interessa..
Ho capito giusto cosa fa?
Poi ho un dubbio su un ultima ottimizzazione, ci starebbe bene un order by id LIMIT 1 anche alla fine dopo la seconda query (comanderebbe praticamente la prima) tanto per non rischiar di far girare a vuota o più del necessario la prima query? O scasserebbe tutto??
tipo:
SELECT * FROM tabella GROUP BY id HAVING count(id) = (SELECT count(id) AS n_trovati FROM tabella GROUP BY id ORDER BY n_trovati DESC LIMIT 1) ORDER BY id LIMIT 1Un ultima cosa, non avevo mai concepito l'idea di utilizzar una query come parametro di una query.. mi hai aperto un mondo... forse in futuro mi risparmierò un sacco di tempo e di codice... grazie
-
Si hai capito bene su come funziona.
Se hai 2 id che sono presenti lo stesso numero di volte, ed inserisci il limit non otterrai ciò che volevi.
Inserire quel limit per ottimizzare la query è, a mio avviso, inutile in quanto deve comunque controllare l'intera tabella per effettuare il raggruppamento, una cosa che potresti fare per aumentare la velocità di lettura della query è mettere il campo id come indice.
Ho fatto un test in locale, con 5000 dati inseriti nella tabella senza indice la query impiega al massimo 0.0092 sec, mentre utilizzando l'indice impiega meno di metà del tempo. I tempi li ho presi con la cache disabilitata, per cui direi che non dovresti avere grandissimi problemi.Le subquery esistono da parecchio tempo in MySQL in alcuni casi possono tornare utili.
-
Grazie mille... capito, come indice ho usato un id_riga in autoincrement, forse però a questo punto non serve a un tubo... magari lo levo e metto l'id ricercato?
Per non rischiar di fare impiegare troppo tempo alla query nel cercar tra troppe righe ho anche pensato, di chiamarla "il più visto della settimana" cosi cancello man mano tutti i record che son li da più di 7 giorni, e salvo non mi facciano centinaia di migliaia di visualizzazioni al giorno (magari accadesse...) non dovrei correre il rischio di tempi troppo lunghi, anche se inserendo una riga per ogni visualizzazione sicuramente ci saranno molte record duplicati.
-
No, non devi creare un nuovo campo come indice ma impostare quello che viene poi utilizzato nella query.
-
Un ultimo dubbio...
Ho provato a impostare l'id come primary key , ma non gli piace, credo proprio perche id può essere duplicato.
Fatto cosi
CREATE TABLE IF NOT EXISTSanimali_video_vis_settimana
(
id_video
int(11) NOT NULL,
id_animale
int(11) NOT NULL,
video
varchar(255) NOT NULL,
data_ins
varchar(255) NOT NULL,
PRIMARY KEYid_video
(id_video
)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;Dice cosi
ErroreQuery SQL:
--
-- Dump dei dati per la tabellaanimali_video_vis_settimana
INSERT INTO
animali_video_vis_settimana
(id_video
,id_animale
,video
,data_ins
)
VALUES ( 1, 13, 'EVXz3i9GVqc', '1343256423' ) , ( 1, 13, 'EVXz3i9GVqc', '1343256431' ) , ( 1, 13, 'EVXz3i9GVqc', '1343256440' ) , ( 4, 13, 'PPqpNv6m1To', '1343317797' ) , ( 4, 13, 'PPqpNv6m1To', '1343317804' ) , ( 4, 13, 'PPqpNv6m1To', '1343317808' ) , ( 4, 13, 'PPqpNv6m1To', '1343317844' ) , ( 6, 13, 'dXHUVw_QHMw', '1343341072' ) , ( 6, 13, 'dXHUVw_QHMw', '1343341077' ) , ( 6, 13, 'dXHUVw_QHMw', '1343341090' ) , ( 6, 13, 'dXHUVw_QHMw', '1343341093' ) , ( 6, 13, 'dXHUVw_QHMw', '1343341108' ) , ( 6, 13, 'dXHUVw_QHMw', '1343341114' ) ;Messaggio di MySQL: Documentazione
#1062 - Duplicate entry '1' for key 1Basta key senza primary???
-
Si devi mettere come semplice key, visto che sono valori ripetuti.
-
Ciao, cercando sul forum ho trovato questo messaggio che "penso" possa aiutarmi.
Mi trovo in una situazione dove a fronte di una ricerca devo restituire un risultato composto da una struttura e più partenze.
Nel dettaglio:
ho 2 tabelle una prodotti e una servizi. Dal form di ricerca cerco tutti gli hotel che sono in una destinazione che hanno delle partenze dal ....
la query di risposta che ho scritto è così composta:SELECT * FROM catalog_service AS s INNER JOIN catalog AS p ON s.lid=p.lid WHERE s.departure >='datapartenza' AND p.template=4 ORDER BY s.sid DESC LIMIT 0,10;
La query funziona ma così nel successivo ciclo while ,mi restituisce lo stesso hotel ripetutto per il numero di partenze, io invece vorrei avere solo 1 hotel con tutte le sue partenze.
Pensavo che la soluzione fosse nel GROUP by e ho preso spunto dalla vostra risposta....ma non ci ho capito niente.Ciao e Grazie
-
Ciao,
riapro questo post perchè ho una piccolissima variante da fare sulla soluzione dell'altra volta.Vorrei non più solo il più visto, ma "i più visti", esempio i 5 più visti di questa settimana
Ho subito pensato bastasse cambiare il limit a questa query e fare un while..
SELECT * FROM tabella GROUP BY id HAVING count(id) = (SELECT count(id) AS n_trovati FROM tabella GROUP BY id ORDER BY n_trovati DESC LIMIT 1)Ma a mysql non piace... dice...
#1242 - Subquery returns more than 1 rowCome ne esco??
Si può fare con questo tipo di query?Ciao
Grazie
-
Togli il group by dalla subquery e funziona, anche perchè non credo proprio che ti serva visto che usa l'id.
-
Non mostra piu nulla senza group
$query_piu_visti = "SELECT * FROM ".$prefix."piu_visti_sett GROUP BY id_news HAVING count(id_news) = (SELECT count(id_news) AS n_trovati FROM ".$prefix."piu_visti_sett ORDER BY n_trovati DESC LIMIT 5)";
//echo $query_piu_visti;
$piu_visti_query = mysql_query($query_piu_visti, $db);
while($row_piu_visti = mysql_fetch_array($piu_visti_query)){
-
Ma a cosa ti serve la subquery in questo caso? Perchè non ordini usando il count e applichi un limit?
-
Fondamentalmente perche ora non so come toglierla...
Cioè dopo having uguale cosa metto?
SELECT * FROM ".$prefix."piu_visti_sett GROUP BY id_news HAVING count(id_news) =..........
-
Puoi postare la struttura di piu_visti_sett?
-
Fatta cosi semplice semplice
CREATE TABLE IF NOT EXISTSstreaming_up_tv_piu_visti_sett
(
id_news
int(11) NOT NULL,
titolo
varchar(255) NOT NULL,
img
varchar(255) NOT NULL,
data_ins
varchar(255) NOT NULL,
KEYid_news
(id_news
)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;Poi sulla pagina di output del singolo post inserisco e cancello i più vecchi di una settimana
-
E' davvero cosi un casino???
Di solito rispondi molto veloce...
-
Ho provato cosi
SELECT count(id_news) AS n_trovati, id_news, titolo, img FROM ".$prefix."piu_visti_sett GROUP BY id_news ORDER BY n_trovati DESC LIMIT 5Cioè togliendo la parte a sinistra di having ed effettivamente ne mostra 5 e non sembra lamentarsi più di tanto...
Ho però qualche dubbio sull'ordinamento, cioè sul fatto che siano effettivamente i 5 più visitati... Secondo voi??? Saranno giusti con la query scritta cosi?
-
Ciao,
vorrei riaprire questa discussione perche ho un altra query un pò diversa da quelle che si usano di solito. E mi sembra cosa carina dare in un solo posto diverse risposte a problemi particolari...Ho un db con questa struttura
id_campagna
clicks_rimanenti
clicks_consumatiVorrei estrarre dal database l'id di una campagna che non ha ancora esaurito i clicks.
Si potrebbe fare in phpcon diverse query, ma sono sicuro (anche se non l'ho mai usato) che esiste un modo per farlo usando la clausola where di mysql.Qualcosa tipo
SELECT * FROM campagne WHERE clicks < clicks_consumatidove click e clicks_consumati sono 2 campi mysql e non variabili php ( forse funziona già cosi come l'ho scritta)
Secondo voi funziona? Altrimenti come si scrive?