Visualizzazione risultati 1 fino 10 di 10

Discussione: [php/mysql] Query DISTINCT "particolare"

  1. #1
    Guest

    Question [php/mysql] Query DISTINCT "particolare"



    Sto cercando di creare un sistema di like identico a quello di questo forum (o di Facebook, per intenderci).
    Quando metto mi piace, viene creata una nuova riga con l'ID dell'utente che mette mi piace, l'ID del post al quale esprimo il gradimento, 1 (che sta per "mi piace messo") e il timestamp. Quando levo il mi piace, non viene apportata alcuna modifica alla riga precedente, ma ne viene creata una nuova identica se non per il fatto che, nella colonna Liked, al posto di 1 viene messo 0 (che quindi sta per "mi piace tolto").
    Il problema viene quando devo calcolare quanti utenti hanno messo mi piace, calcolando anche quelli che l'hanno levato.

    Codice:
    SELECT DISTINCT IDUtente FROM PostLike WHERE IDPost = $ID ORDER BY Time DESC
    Questa è la query quasi completa, l'unico problema è che non so come selezionare soltanto quelli con valore Liked uguale a 1, poiché aggiungendo WHERE Liked = 1 comunque non sa che dopo quell'1 c'è uno 1 (mi piace levato) che va preso in considerazione.

    Grazie
    Ultima modifica di lucart98 : 03-01-2014 alle ore 00.13.17 Motivo: Migliorato screenshot tabella

  2. #2
    L'avatar di radiodelmomento
    radiodelmomento non è connesso AlterGuru
    Data registrazione
    09-09-2010
    Messaggi
    1,075

    Predefinito

    Oddio oggi sto delirando con questo "switch" continuo di account
    Comunque sono sempre io

  3. #3
    L'avatar di saitfainder
    saitfainder non è connesso Sëniör Stäff
    Data registrazione
    06-12-2002
    Residenza
    Torino
    Messaggi
    8,715

    Predefinito

    La distinct ti permette di eliminare righe duplicate, non di fare considerazioni sui contenuti di righe diverse. Quindi mi sembra che il tuo richiesta possa riassumersi come "voglio tutte le righe Liked=1 per cui non esiste una riga Liked=0 per lo stesso utente e post" che in SQL diventa:

    Codice:
    SELECT t1.IDUtente
    FROM PostLike AS t1
    WHERE t1.IDPost = $ID
    AND t1.Liked = 1
    AND NOT EXISTS (
      SELECT 1
      FROM PostLike AS t2
      WHERE t2.IDPost = t1.IDPost
      AND t2.IDUtente = t1.IDUtente
      AND t2.Liked = 0
    )


    «È una mia peculiarità distorcere la verità e inventarne di nuove.»
    «I tuoi orientamenti hanno su di me un effetto prossimo allo zero.»


  4. #4
    L'avatar di radiodelmomento
    radiodelmomento non è connesso AlterGuru
    Data registrazione
    09-09-2010
    Messaggi
    1,075

    Predefinito

    Aspetta... un utente può anche aver messo like, tolto e rimesso, quindi avremo anche un Liked=0, ma io devo contarlo perché l'ultima azione è Liked=1. Utilizzo DISTINCT perché devo prendere in considerazione una sola riga per ogni utente (l'ultima), e fino a qui ci siamo. Il problema è contare, di tutte queste righe, soltanto quelle che hanno Liked=1.

  5. #5
    L'avatar di javascripter
    javascripter non è connesso Moderatore
    Data registrazione
    14-02-2010
    Messaggi
    1,114

    Predefinito

    Sei sicuro che tutta quella ridondanza di dati sia utile?
    Comunque, non ho capito cosa dovrebbe fare una query. Dato l'id del post vuoi ottenere il numero dei 'mi piace'?

    Se è così, questa dovrebbe funzionare:
    Codice:
    SELECT COUNT(*) AS mipiace FROM 
      (SELECT * FROM (
        SELECT * FROM LikePost WHERE 
        IDPost = $ID
        ORDER BY Time DESC
      ) u
      WHERE Liked = 1
      GROUP BY IDUtente ASC) n
    Comunque, piuttosto che ORDER BY Time si potrebbe anche usare ORDER BY ID, dato che l'id è univoco (e auto_increment a quanto vedo). Il timestamp poi puoi usarlo per altra roba se proprio ti serve.
    Ultima modifica di javascripter : 03-01-2014 alle ore 15.27.28

  6. #6
    L'avatar di radiodelmomento
    radiodelmomento non è connesso AlterGuru
    Data registrazione
    09-09-2010
    Messaggi
    1,075

    Predefinito

    Grazie, ma continua a non tener conto del successivo Liked=0.
    Ultima modifica di radiodelmomento : 03-01-2014 alle ore 18.54.13

  7. #7
    L'avatar di javascripter
    javascripter non è connesso Moderatore
    Data registrazione
    14-02-2010
    Messaggi
    1,114

    Predefinito

    Citazione Originalmente inviato da radiodelmomento Visualizza messaggio
    Grazie, ma continua a non tener conto del successivo Liked=0.
    Credo di aver sbagliato il posizionamento della clausola WHERE, prova così:
    Codice:
    SELECT COUNT(*) FROM (
    SELECT * FROM (
        SELECT * FROM PostLike WHERE 
        IDPost = $ID
        ORDER BY Time DESC
      ) u
      GROUP BY IDUtente ASC) n
    WHERE Liked = 1

  8. #8
    L'avatar di radiodelmomento
    radiodelmomento non è connesso AlterGuru
    Data registrazione
    09-09-2010
    Messaggi
    1,075

    Predefinito

    Grazie mille, adesso funziona alla grande.
    Mi sapresti dire (o linkare) che significano "u" ed "n" che non so proprio come cercare?

  9. #9
    L'avatar di javascripter
    javascripter non è connesso Moderatore
    Data registrazione
    14-02-2010
    Messaggi
    1,114

    Predefinito

    Sono degli alias, è come se prima ci fosse AS. Per le query annidate, è obbligatorio specificare un alias. Pertanto ne ho scelti due casuali (i primi che mi sono venuti in mente)... anche se è consigliabile dare un nome più esplicito.

    La prima query estrae i dati, la seconda li raggruppa ('eliminando' i valori multipli e lasciando solo quelli col timestamp più alto) e la terza li conta.

  10. #10
    L'avatar di radiodelmomento
    radiodelmomento non è connesso AlterGuru
    Data registrazione
    09-09-2010
    Messaggi
    1,075

    Predefinito

    Ah perfetto così in teoria potrei anche recuperare i valori delle singole query
    Grazie mille

Regole di scrittura

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