Visualizzazione risultati 1 fino 16 di 16

Discussione: Union, Select, Left Join, Group by in una query.

  1. #1
    Guest

    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:
    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

  2. #2
    L'avatar di dementialsite
    dementialsite non è connesso Super Moderatore
    Data registrazione
    19-10-2004
    Residenza
    fuori Padova
    Messaggi
    5,046

    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

    ALTERVISTA WANTS YOU!
    Vuoi diventare moderatore su AlterVista? Scopri come...

  3. #3
    Guest

    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?

  4. #4
    Guest

    Predefinito

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


    Ciao!

  5. #5
    L'avatar di dementialsite
    dementialsite non è connesso Super Moderatore
    Data registrazione
    19-10-2004
    Residenza
    fuori Padova
    Messaggi
    5,046

    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

    ALTERVISTA WANTS YOU!
    Vuoi diventare moderatore su AlterVista? Scopri come...

  6. #6
    Guest

    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

  7. #7
    L'avatar di dementialsite
    dementialsite non è connesso Super Moderatore
    Data registrazione
    19-10-2004
    Residenza
    fuori Padova
    Messaggi
    5,046

    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

    ALTERVISTA WANTS YOU!
    Vuoi diventare moderatore su AlterVista? Scopri come...

  8. #8
    Guest

    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

  9. #9
    L'avatar di dementialsite
    dementialsite non è connesso Super Moderatore
    Data registrazione
    19-10-2004
    Residenza
    fuori Padova
    Messaggi
    5,046

    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

    ALTERVISTA WANTS YOU!
    Vuoi diventare moderatore su AlterVista? Scopri come...

  10. #10
    Guest

    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?

  11. #11
    L'avatar di dementialsite
    dementialsite non è connesso Super Moderatore
    Data registrazione
    19-10-2004
    Residenza
    fuori Padova
    Messaggi
    5,046

    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...
    Ultima modifica di dementialsite : 13-11-2009 alle ore 13.41.00
    Le questioni tecniche hanno risposte migliori nel forum pubblico, non trovi?

    When you don't know your next step... improvise

    ALTERVISTA WANTS YOU!
    Vuoi diventare moderatore su AlterVista? Scopri come...

  12. #12
    Guest

    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?

  13. #13
    L'avatar di dementialsite
    dementialsite non è connesso Super Moderatore
    Data registrazione
    19-10-2004
    Residenza
    fuori Padova
    Messaggi
    5,046

    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

    ALTERVISTA WANTS YOU!
    Vuoi diventare moderatore su AlterVista? Scopri come...

  14. #14
    Guest

    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.

  15. #15
    L'avatar di dementialsite
    dementialsite non è connesso Super Moderatore
    Data registrazione
    19-10-2004
    Residenza
    fuori Padova
    Messaggi
    5,046

    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

    ALTERVISTA WANTS YOU!
    Vuoi diventare moderatore su AlterVista? Scopri come...

  16. #16
    Guest

    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.

Regole di scrittura

  • Non puoi creare nuove discussioni
  • Non puoi rispondere ai messaggi
  • Non puoi inserire allegati.
  • Non puoi modificare i tuoi messaggi
  •