Torna indietro   AlterVista | Spazio web gratis, hosting free php mysql > Supporto > PHP, MySql e file database

Rispondi
 
LinkBack Strumenti discussione Modalità visualizzazione
  #1 (permalink)  
Vecchio 12-11-2009, 01.06.08
L'avatar di biccheddu
AlterGuru
 
Data registrazione: 18-01-2009
Residenza: Sant'Antioco
Messaggi: 1,974
Invia un messaggio via MSN a biccheddu Invia un messaggio via Yahoo a biccheddu Manda un messaggio tramite Skype™ a biccheddu
Predefinito Union, Select, Left Join, Group by in una query.

Vorrei sapere cosa c'è di sbagliato in questa query:
Codice:
SELECT * FROM contests
LEFT JOIN contests_participants
	ON (participant_id = 2) AND (participant_contest = contest_id)
UNION
	SELECT COUNT(participant_id) AS participants
	FROM contests_participants
	GROUP BY participant_contest
Mi restituisce sempre:
Citazione:
The used SELECT statements have a different number of columns [#1222]
Dovrei contare un certo dato raggruppandolo per id. Se avete altre soluzioni sono tutto orecchi
__________________
· Federico Biccheddu
Rispondi citando
  #2 (permalink)  
Vecchio 12-11-2009, 09.47.51
L'avatar di dementialsite
Super Moderatore
 
Data registrazione: 19-10-2004
Residenza: fuori Padova
Messaggi: 3,798
Manda un messaggio tramite Skype™ a dementialsite
Predefinito

Quando esegui la UNION i record restituiti dalle due query devono essere "compatibili per unione", ovvero non solo avere lo stesso numero di campi ma anche i rispettivi domini (numerico intero, numerico decimale, stringa e simili) nella stessa posizione. Questo perché il risultato sarà una singola tabella dove confluiranno i risultati delle due query, con la condizione che saranno inseriti nel recordset risultante se soddisfano almeno una delle due query (se utilizzassi INTERSECT le dovrebbe soddisfare entrambe).

Per correggerti la query però sarebbe meglio che fornissi altre informazioni, come la struttura delle tabelle coinvolte: così potresti anche definire meglio qual è il record che devi contare...

Stammi bene...
__________________
Le questioni tecniche hanno risposte migliori nel forum pubblico, non trovi?

When you don't know your next step... improvise
DEMENTIAL SITE V - più nuovo, più bello, più community!
Rispondi citando
  #3 (permalink)  
Vecchio 12-11-2009, 09.57.19
L'avatar di biccheddu
AlterGuru
 
Data registrazione: 18-01-2009
Residenza: Sant'Antioco
Messaggi: 1,974
Invia un messaggio via MSN a biccheddu Invia un messaggio via Yahoo a biccheddu Manda un messaggio tramite Skype™ a biccheddu
Predefinito

Allora, ho una tabella dove ci sono i dati di un concorso con 8 campi, nella seconda tabella ho due campi dove registro l'id dell'utente e l'id del concorso.
Quando sono nella lista dei concorsi devo scrivere per ogni concorso quanti utenti partecipano (credo per questo sia utile il GROUP BY) per ogni concorso. Ecco un esempio:
prima tabella:
Codice:
contest_id 	contest_name 	contest_type 	contest_status 	contest_start 	contest_finish 	contest_open 	contest_winner
1 		Prova 		1 		0 		1257977977 	1287698400 	2 		2 	  	  	 
2 		Prova  		1 		0 		1257977977 	1257987000 	2 		2
La seconda:
Codice:
participant_id 	participant_contest
2 		1
2 		2
Nella listm, attraverso un while, mostro tutti i concorsi presenti nella prima tabella, quindi devo contare quanti utenti partecipano (nella seconda).
Capito il mio problema?
__________________
· Federico Biccheddu
Rispondi citando
  #4 (permalink)  
Vecchio 12-11-2009, 10.45.01
L'avatar di debug
Amministratore del forum
 
Data registrazione: 27-01-2004
Messaggi: 16,871
Predefinito

Credo che nella seconda tabella tu abbia sbagliato il nome dei campi oppure il loro contenuto (non possono esserci due ID uguali)


Ciao!
__________________
[ debug 2.0 | deForum 3.0? Suggerisci | deGallery 5.1! | deGuest | guardali in faccia | MillenniuMRoma.it ]



Non rispondo a messaggi privati su argomenti tecnici. Per queste cose esiste il forum! © ® ™
Rispondi citando
  #5 (permalink)  
Vecchio 12-11-2009, 11.07.50
L'avatar di dementialsite
Super Moderatore
 
Data registrazione: 19-10-2004
Residenza: fuori Padova
Messaggi: 3,798
Manda un messaggio tramite Skype™ a dementialsite
Predefinito

Se vuoi usare solo l'ID dei concorsi, basta usare la seconda tabella:
Codice:
SELECT participant_contest, COUNT (*)
FROM contest_participants
GROUP BY participant_contest
La JOIN (o la WHERE in vecchio stile) ti serve se vuoi anche il nome del concorso:
Codice:
SELECT participant_contest, contest_name, COUNT (*)
FROM contest_participants, contests
WHERE participant_contest = contest_id
GROUP BY participant_contest, contest_name
Stammi bene...
__________________
Le questioni tecniche hanno risposte migliori nel forum pubblico, non trovi?

When you don't know your next step... improvise
DEMENTIAL SITE V - più nuovo, più bello, più community!
Rispondi citando
  #6 (permalink)  
Vecchio 12-11-2009, 17.41.42
L'avatar di biccheddu
AlterGuru
 
Data registrazione: 18-01-2009
Residenza: Sant'Antioco
Messaggi: 1,974
Invia un messaggio via MSN a biccheddu Invia un messaggio via Yahoo a biccheddu Manda un messaggio tramite Skype™ a biccheddu
Predefinito

Non sono ID auto increment, ma sono ID che registrano l'utente e il concorso, poi attraverso un indice di tipo PRIMARY evito che ci siano contenuti doppi.

La query che mi mostra la lista di tutti i concorsi è questa:
Codice:
SELECT * FROM contests
LEFT JOIN contests_participants
	ON (participant_id = 2) AND (participant_contest = contest_id)
Poi come scritto, in un while li mostro tutti.
Ora, per ogni record della tabella contest, devo contare quanti utenti partecipano. Quindi, per non fare un'altra query nel while per ogni concorso, mi pare strano non ci sia soluzione simile a quello che vorrei.
Con la seconda query chehai postato mi mostra solo i concorsi dove ci sono partecipanti, non tutti i concorsi.

Grazie del supporto
__________________
· Federico Biccheddu
Rispondi citando
  #7 (permalink)  
Vecchio 12-11-2009, 18.01.10
L'avatar di dementialsite
Super Moderatore
 
Data registrazione: 19-10-2004
Residenza: fuori Padova
Messaggi: 3,798
Manda un messaggio tramite Skype™ a dementialsite
Predefinito

Potresti provare quindi così:
Codice:
SELECT participant_contest, contest_name, COUNT (*)
FROM contest_participants RIGHT JOIN contests ON participant_contest = contest_id
GROUP BY participant_contest, contest_name
Se non funzionasse (perché ti conta per 1 anche i record con la parte sinistra a NULL), non puoi fare altro che estrarli manualmente con la UNION:
Codice:
SELECT participant_contest, contest_name, COUNT (*)
FROM contest_participants, contests
WHERE participant_contest = contest_id
GROUP BY participant_contest, contest_name

UNION SELECT contest_id, contest_name, 0
FROM contests
WHERE contest_id NOT IN (SELECT participant_contest FROM contest_participants)
(la query dovrebbe essere corretta, ma non credo MySQL 4 installato su AV supporti le query annidate).

Stammi bene...
__________________
Le questioni tecniche hanno risposte migliori nel forum pubblico, non trovi?

When you don't know your next step... improvise
DEMENTIAL SITE V - più nuovo, più bello, più community!
Rispondi citando
  #8 (permalink)  
Vecchio 12-11-2009, 18.22.35
L'avatar di biccheddu
AlterGuru
 
Data registrazione: 18-01-2009
Residenza: Sant'Antioco
Messaggi: 1,974
Invia un messaggio via MSN a biccheddu Invia un messaggio via Yahoo a biccheddu Manda un messaggio tramite Skype™ a biccheddu
Predefinito

Ora lavoro in locale con MySQL 5.1.37, mentre in remoto ho la 5.0.82, ma credo che inizierò su AV e forse ci sarà anche l'aggiornamento prima che finisca lo script

La seconda query l'ho modificata leggermente e funziona, solo che mi mostra nel campo contest_id il seguente record: [BLOB - 1B] o [BLOB - 7B] e poi mi mischia i dati, cioè nel while quando li mostra inverte l'id con il nome quindi mi incasina anche la generazione del link

Scusa, ma come ho già sritto in altri topic sono duro di comprendonio, ma la voglia di imparare è abbastanza
__________________
· Federico Biccheddu
Rispondi citando
  #9 (permalink)  
Vecchio 13-11-2009, 09.15.23
L'avatar di dementialsite
Super Moderatore
 
Data registrazione: 19-10-2004
Residenza: fuori Padova
Messaggi: 3,798
Manda un messaggio tramite Skype™ a dementialsite
Predefinito

Io sopra ho assunto (credo ragionevolmente, anche se non me l'hai scritto) che:
- participant_contest (tabella contest_participants) sia una chiave esterna per il campo contest_id (tabella contests)
- entrambe siano di tipo numerico intero
È corretto, o c'è qualcosa che mi è sfuggito?

Se così è, non riesco a capire né perché ti venga riconosciuto come un BLOB (oggetto binario), né tantomeno perché ti scambi le colonne (che devo aver dichiarato in modo che siano "compatibili per unione").

Stammi bene...
__________________
Le questioni tecniche hanno risposte migliori nel forum pubblico, non trovi?

When you don't know your next step... improvise
DEMENTIAL SITE V - più nuovo, più bello, più community!
Rispondi citando
  #10 (permalink)  
Vecchio 13-11-2009, 10.24.26
L'avatar di biccheddu
AlterGuru
 
Data registrazione: 18-01-2009
Residenza: Sant'Antioco
Messaggi: 1,974
Invia un messaggio via MSN a biccheddu Invia un messaggio via Yahoo a biccheddu Manda un messaggio tramite Skype™ a biccheddu
Predefinito

La prima tabella (contests) ha tutti i dati dei contest, la seconda (contests_partecipants) invece raccoglie gli utenti iscritti. Per sapere a quli contest un utente si è iscritto ovviamente devo inserire l'id dell'utente e quello del concorso.
Ora, siccome nella seconda tabella avrò obbligatoriamente record uguali, ma non righe uguali, cioè non potrò avere lo stesso utente iscritto due volte allo stesso contest, avrei voluto contare gli utenti iscritti in ogni contest nella stessa query che li prende e li mostra nella lista.
Faccio un altro esempio:
Una stanza di un forum ha tanti argomenti dentro. Ora, per sapere che quegli argomenti sono di quella determinata astanza, nell'argomento salvi anche l'id della stanza.
Quando vai a mostrare la lista delle stanza, senza eseguire in più una query per ogni stanza in modo da contare gli argomenti, è possibile fare questo nella query che seleziona queste stanze?
__________________
· Federico Biccheddu
Rispondi citando
  #11 (permalink)  
Vecchio 13-11-2009, 12.39.08
L'avatar di dementialsite
Super Moderatore
 
Data registrazione: 19-10-2004
Residenza: fuori Padova
Messaggi: 3,798
Manda un messaggio tramite Skype™ a dementialsite
Predefinito

Citazione:
Originalmente inviato da biccheddu Visualizza messaggio
La prima tabella (contests) ha tutti i dati dei contest, la seconda (contests_partecipants) invece raccoglie gli utenti iscritti. Per sapere a quli contest un utente si è iscritto ovviamente devo inserire l'id dell'utente e quello del concorso.
Ok, fino a qui ci siamo: l'id dell'utente e l'id del concorso sono chiavi esterne verso le rispettive tabelle (perché l'id del concorso deve essere presente come id nella tabella dei concorsi, questo è il significato)
Citazione:
Originalmente inviato da biccheddu Visualizza messaggio
Ora, siccome nella seconda tabella avrò obbligatoriamente record uguali, ma non righe uguali, cioè non potrò avere lo stesso utente iscritto due volte allo stesso contest, avrei voluto contare gli utenti iscritti in ogni contest nella stessa query che li prende e li mostra nella lista.
Se ho capito bene il problema, non puoi farlo con una singola query: te ne serve una per visualizzare il riepilogo, e un'altra per visualizzare i dati dei singoli iscritti. Quest'ultima puoi realizzarla mantenendo tutti i dati nella stessa tabella ed eseguendo un preciso ordinamento, mantenendo vicini i record che vanno elaborati insieme: in questo modo, saprai che dovrai passare al concorso successivo quando, scandendo la lista, "si rompe" questo criterio.

La prima query te la dovrei aver scritto sopra, se mi confermi che funziona.

La seconda, invece, l'hai scritta tu o quasi: se togli la condizione sui partecipanti, dovresti riuscire, elaborando le due query "in parallelo", a distinguere quali sono i concorsi senza partecipanti (perché hanno il contatore della prima query pari a 0).

Stammi bene...
__________________
Le questioni tecniche hanno risposte migliori nel forum pubblico, non trovi?

When you don't know your next step... improvise
DEMENTIAL SITE V - più nuovo, più bello, più community!

Ultima modifica di dementialsite : 13-11-2009 alle ore 12.41.00
Rispondi citando
  #12 (permalink)  
Vecchio 13-11-2009, 22.04.40
L'avatar di biccheddu
AlterGuru
 
Data registrazione: 18-01-2009
Residenza: Sant'Antioco
Messaggi: 1,974
Invia un messaggio via MSN a biccheddu Invia un messaggio via Yahoo a biccheddu Manda un messaggio tramite Skype™ a biccheddu
Predefinito

Che casino, non ci capisco niente, mi sa che creerò un campo nella tabella dei contest che verrà incrementato e basta, tanto non ci si può cancellare dal concorso, mi semplifico la vita no?
__________________
· Federico Biccheddu
Rispondi citando
  #13 (permalink)  
Vecchio 14-11-2009, 18.30.30
L'avatar di dementialsite
Super Moderatore
 
Data registrazione: 19-10-2004
Residenza: fuori Padova
Messaggi: 3,798
Manda un messaggio tramite Skype™ a dementialsite
Predefinito

Citazione:
Originalmente inviato da biccheddu Visualizza messaggio
Che casino, non ci capisco niente, mi sa che creerò un campo nella tabella dei contest che verrà incrementato e basta, tanto non ci si può cancellare dal concorso, mi semplifico la vita no?
Puoi fare anche così, è una soluzione molto usata: si chiama ridondanza.

Attento, però, le ridondanze sono delle "armi a doppio taglio": semplifichi qualche elaborazione, ma il costo è quello di un aggiornamento che deve essere fatto sempre "in parallelo", pena l'inconsistenza dei dati (ovvero, ottieni dati non corrispondenti alla realtà).

Stammi bene...
__________________
Le questioni tecniche hanno risposte migliori nel forum pubblico, non trovi?

When you don't know your next step... improvise
DEMENTIAL SITE V - più nuovo, più bello, più community!
Rispondi citando
  #14 (permalink)  
Vecchio 14-11-2009, 18.35.02
L'avatar di biccheddu
AlterGuru
 
Data registrazione: 18-01-2009
Residenza: Sant'Antioco
Messaggi: 1,974
Invia un messaggio via MSN a biccheddu Invia un messaggio via Yahoo a biccheddu Manda un messaggio tramite Skype™ a biccheddu
Predefinito

Cioè? non ho capito quel che intendi.
Esempio stupido: phpBB salva nella tabella dei topic il numero di risposte e il reale numero di risposta (cioè il numero di risposte senza quelle non approvate ecc).
Ogni qual volta che un utente si iscriverà basterà fare un incremento del dato no? Questo sarà in ogni riga della tabella.
__________________
· Federico Biccheddu
Rispondi citando
  #15 (permalink)  
Vecchio 15-11-2009, 17.01.23
L'avatar di dementialsite
Super Moderatore
 
Data registrazione: 19-10-2004
Residenza: fuori Padova
Messaggi: 3,798
Manda un messaggio tramite Skype™ a dementialsite
Predefinito

Citazione:
Originalmente inviato da biccheddu Visualizza messaggio
... Ogni qual volta che un utente si iscriverà basterà fare un incremento del dato no? Questo sarà in ogni riga della tabella.
È proprio questo il problema a cui mi riferivo: gestire delle ridondanze su un database richiede che ci si faccia carico di tutte le operazioni, sia durante l'inserimento che durante la cancellazione.

Tipico esempio realizzato sui forum è il contatore dei messaggi: di solito viene implementato per ridondanza, perché contare le righe di una tabella solo per stampare un numero è un lavoro eccessivamente gravoso. Questo, però, ti richiede due operazioni ad ogni invio o cancellazione di un messaggio: una per il messaggio vero e proprio, e l'altra per aggiornare il contatore.

Prima di inserire una ridondanza sul database, ti conviene eseguire delle valutazioni: se il numero di operazioni supplementari necessarie a gestire la ridondanza (di solito gli aggiornamenti) è minore degli accessi al dato ridondato (di solito le ricerche), allora è conveniente gestirla. Per calcolare il numero di operazioni, devi fare una stima degli utenti e delle loro azioni, nel tuo caso:
- quanti utenti accedono alla tua applicazione?
- quanti si iscrivono ad un concorso?
- quanti, invece, sono "interessati" a conoscere il numero di iscritti di un concorso?

Stammi bene...
__________________
Le questioni tecniche hanno risposte migliori nel forum pubblico, non trovi?

When you don't know your next step... improvise
DEMENTIAL SITE V - più nuovo, più bello, più community!
Rispondi citando
  #16 (permalink)  
Vecchio 15-11-2009, 17.07.05
L'avatar di biccheddu
AlterGuru
 
Data registrazione: 18-01-2009
Residenza: Sant'Antioco
Messaggi: 1,974
Invia un messaggio via MSN a biccheddu Invia un messaggio via Yahoo a biccheddu Manda un messaggio tramite Skype™ a biccheddu
Predefinito

Questo dipende, io sto creando il sito e spero un giorno sia frequentato perchè non ci sono molti di questi che hanno quello che sto creando, quindi le prime due dipendono da quanto appena detto, mentre la terza credo che dipenda da una cosa: un concorso molto gettonato porta altra gente ad iscriversi, però effettivamente potrei mostrare il numero nella pagina apposita del concorso quando mostro tutti gli utenti iscritti. In questo modo risparmierei un campo per ogni concorso, un dato in meno da estrarre e una query in meno quando un utente si iscrive al concorso, credo sia molto tutto questo.
__________________
· Federico Biccheddu
Rispondi citando
Rispondi

Strumenti discussione
Modalità visualizzazione

Regole di scrittura
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Attivato
Le faccine sono Attivato
Il codice [IMG] è Attivato
Il codice HTML è Disattivato
Trackbacks are Attivato
Pingbacks are Attivato
Refbacks are Disattivato



Tutti gli orari sono GMT +1. Adesso sono le 06.09.39.