• User Newbie

    PHP MySQL voti comparativi univoci

    Buonasera,

    per caso avreste modo di consigliarmi letture o video o tutorial o nomi di sistemi/algoritmi da studiare in cui viene trattato qualcosa in merito alla creazione di un sistema di votazione per comparazione. Per chiarezza lo metto sotto esempio:

    • Ci sono X elementi in tabella "elementi"
    • Ci sono Y utenti in tabella "utenti"
    • Ogni utente visualizza due elementi X e può scegliere quale dei due preferisce, quindi salvo la preferenza in una terza tabella
    • Dopo la prima scelta non posso più scegliere i due elementi X in modo random, in che modo posso esser certo di "dare in pasto" all'utente due elementi X che non ha già comparato in precedenza? Potrei andare con selezioni random e solo dopo verificare se l'utente ha già votato per questa comparazione, ma ipoteticamente al termine (o vicini al termine) delle comparazioni a disposizione il sistema andrebbe in loop all'infinito perché continuerebbe a proporre confronti random senza mai beccare un confronto mai votato, se l'utente li ha già votati tutti...

    Non so se mi sono spiegato bene, spero si capisca. Se devo rispiegare ditemi pure che ci riprovo..

    Grazie!


  • User Attivo

    Spero di aver capito... vediamo.

    Tabellautenti:
    ID|Name
    1|Gino
    2|Pino
    
    TabellaElementi:
    ID|Elemento
    1|Primo
    2|Secondo
    3|Terzo
    4|Quarto
    5|Quinto
    6|Sesto
    
    TabellaArchivio
    ID|IDUtente|Selezione|NonSelezione
    1|2|3|5
    2|2|1|4
    

    Nell'esempio ho registrato due risposte di "Pino" ed in particolare tra "Terzo" e "Quinto" ha scelto "Terzo", mentre tra "Primo" e "Quarto" ha scelto "Primo".
    Se ho compreso giusto al terzo quesito il sistema dovrà proporre solo "Secondo" e "Sesto".

    Quindi, registro nelle risposte sia la scelta che l'opzione scartata e quando devo proporre una domanda nuova selezionerò in maniera casuale due opzioni escludendo le opzioni in qui ho l'utente selezionato e le risposte già presenti

    select id, elemento from TabellaElementi WHERE id NOT IN (SELECT Selezione FROM TabellaArchivio where idUtente = " & idUtente & ") and id NOT IN (SELECT NonSelezione FROM TabellaArchivio where idUtente = " & idUtente & ") order by rand() limit 0,2
    

    Esistono poi alternative... magari leggiti questo articolo che esegue dei test su differenti query per valutare le performance
    https://www.red-gate.com/hub/product-learning/sql-prompt/consider-using-not-exists-instead-not-subquery


  • User Newbie

    Circa si ma in realtà devono essere solo le associazioni univoche.

    Es. con 6 elementi:
    Se si fa comparazione 1-2
    Poi non è che si scartano del tutto 1 e 2 dalle prossime, solamente non si devono più incontrare tra loro.
    Quindi ci saranno anche comparazioni:
    1-3
    1-4
    1-5
    1-6
    2-3
    2-4
    2-5
    2-6
    Etc con tutti gli altri.

    Solo che se nel tempo arrivo a migliaia di elementi, le comparazioni possibili diventerebbero miliardi e non so quanto sia sostenibile. Provo a fare qualche prova con la query suggerita (penso sia da modificare secondo le ultime info che ti ho riportato qui, ci provo e se ho problemi torno ed edito), e provo a leggere anche al link indicato.

    Grazie!

    Edit:
    Potrei pensare se no di aggiungere altra tabella "comparazioni" solo con i due elementi es:

    utenti
    	id	nome
    
    elementi
    	id	nome
    
    comparazioni
    	id	id_elem_1	id_elem_2
    
    votazioni
    	id	id_utente	id_comparazione		scelta_utente (1 o 2)
    

    Quindi dovrei io popolare man mano che aggiungo elementi la tabella comparazioni.
    Es. ho 10 elementi, aggiungo l'11esimo, e dovrei avere una insert che aggiunge in "comparazioni" N righe con id_elem_1 = 11, e id_elem_2 da 1 a N (con N = num. record esistenti).
    Con le query non sono il top, quindi devo capire bene come poter avere una query di inserimento simile.

    E poi ci sarebbe la query per dare all'utente una comparazione random (sarebbe semplice seguire l'id delle comparazioni a salire salvando per ogni utente l'ultimo id comparazione fatta, ma risulterebbe brutto l'effetto finale.. es. dopo 1000 inserimenti ci sarebbero 1000 comparazioni di fila sullo stesso elemento con tutti gli altri..). Quindi dovrei capire se possibile fare una query di select che mi prenda una comparazione a caso, tenendo però conto che non esista già un record in "votazioni" avente lo stesso id_utente ed id_comparazione....


  • User Attivo

    Ah, ok, non devi escludere la domanda se è già stata fatta ma solo l'abbinamento...

    Pensando così al volo:

    1. Fatti una tabella con i possibili abbinamenti
    2. Registri l'abbinamento con l'utente

    Fine della storia


  • User Newbie

    Mi sfugge solo la query per poter poi fare una ricerca random in "comparazioni" escludendo quelle già votate/registrate su "votazioni". Senza cicli o cose strane via PHP (direi evitando query multiple..).

    Questo weekend dovrei avere tempo per tornarci su, provo a cercare/costruirla, sperando sia fattibile.

    Grazie ancora!


  • User Attivo

    Select "abbinamento" from abbinamenti dove non esiste abbinamento ed utente in risposte....
    non devi fare cicli