Badge for posts with Likes from a specific group

As already mentioned here:

Grant a badge to everyone having posted at least <POST_COUNT> posts in the category <CATEGORY_NAME> that have received at least <LIKE_COUNT> likes by users in the group <TEAM_NAME>. Similar to the bug reporter badge here, but can require more than one like.

SELECT p.user_id, min(p.created_at) granted_at, MIN(p.id) post_id
FROM badge_posts p
JOIN topics t ON t.id = p.topic_id
WHERE category_id = (
        SELECT id FROM categories WHERE name ilike '<CATEGORY_NAME>'
    ) AND (
        SELECT count(*)
        FROM post_actions pa
        WHERE pa.post_id = p.id
            AND post_action_type_id = (
                SELECT id FROM post_action_types WHERE name_key = 'like'
            ) AND pa.user_id IN (
                SELECT gu.user_id
                FROM group_users gu
                WHERE gu.group_id = ( SELECT id FROM groups WHERE name ilike '<TEAM_NAME>' ) 
            )
    ) >= <LIKE_COUNT>
    AND p.post_number = 1
    AND p.user_id >= 0
GROUP BY p.user_id
HAVING count(*) >= <POST_COUNT>
6 Mi Piace

Ci stavo armeggiando e quasi ci ero riuscito, ma non riuscivo ad applicarlo a tutte le categorie come volevo. C’è un modo semplice per farlo?

2 Mi Piace

Ciao @Firepup650 :slight_smile: forse prova questo. ha funzionato sulla mia istanza.

<NOME CATEGORIA> = Nome categoria sensibile alle maiuscole (non slug)
<GRUPPO> = Nome gruppo (es: Staff, Trust_level_0)
<NUMERO MINIMO DI LIKE> = numero minimo di like che vuoi impostare
<SOGLIA NUMERO POST> = numero minimo di post
SELECT p.user_id, min(p.created_at) granted_at, MIN(p.id) post_id
FROM badge_posts p
JOIN topics t ON t.id = p.topic_id
WHERE t.category_id = (
        SELECT id FROM categories WHERE name ilike '<NOME CATEGORIA>'
    ) AND (
        SELECT count(*)
        FROM post_actions pa
        WHERE pa.post_id = p.id
            AND post_action_type_id = (
                SELECT id FROM post_action_types WHERE name_key = 'like'
            ) AND pa.user_id IN (
                SELECT gu.user_id
                FROM group_users gu
                WHERE gu.group_id = ( SELECT id FROM groups WHERE name ilike '<NOME GRUPPO>' )
            )
    ) >= <NUMERO MINIMO DI LIKE>
    AND p.user_id >= 0
GROUP BY p.user_id
HAVING count(*) >= <SOGLIA NUMERO POST>

per più categorie puoi fare così:

<NOMI CATEGORIE> = Nomi delle categorie sensibili alle maiuscole
<GRUPPO> = Nome gruppo (es: Staff, Trust_level_0)
<NUMERO MINIMO DI LIKE> = numero minimo di like che vuoi impostare
<SOGLIA NUMERO POST> = numero minimo di post
SELECT p.user_id, min(p.created_at) granted_at, MIN(p.id) post_id
FROM badge_posts p
JOIN topics t ON t.id = p.topic_id
WHERE t.category_id IN (
        SELECT id FROM categories WHERE name ILIKE ANY (ARRAY['<NOME CATEGORIA 1>', '<NOME CATEGORIA 2>', '<NOME CATEGORIA 3>'])
    ) AND (
        SELECT count(*)
        FROM post_actions pa
        WHERE pa.post_id = p.id
            AND post_action_type_id = (
                SELECT id FROM post_action_types WHERE name_key = 'like'
            ) AND pa.user_id IN (
                SELECT gu.user_id
                FROM group_users gu
                WHERE gu.group_id = ( SELECT id FROM groups WHERE name ILIKE '<GRUPPO>' )
            )
    ) >= <NUMERO MINIMO DI LIKE>
    AND p.user_id >= 0
GROUP BY p.user_id
HAVING count(*) >= <SOGLIA NUMERO POST>
1 Mi Piace

Ciao @Lilly!

Entrambe sembrano ottime query, ma volevo solo eseguire la query su tutte le categorie, se possibile. Quando ho provato, ho continuato a ricevere errori riguardo a una sottoquery che restituiva più righe, quindi sono venuto qui a chiedere.

1 Mi Piace

Intendi che desideri la stessa query per tutte le categorie?

SELECT p.user_id, min(p.created_at) granted_at, MIN(p.id) post_id
FROM badge_posts p
JOIN topics t ON t.id = p.topic_id
WHERE (
        SELECT count(*)
        FROM post_actions pa
        WHERE pa.post_id = p.id
            AND post_action_type_id = (
                SELECT id FROM post_action_types WHERE name_key = 'like'
            ) AND pa.user_id IN (
                SELECT gu.user_id
                FROM group_users gu
                WHERE gu.group_id = ( SELECT id FROM groups WHERE name ILIKE '<GROUP>' ) 
            )
    ) >= <MINIMUM LIKE COUNT>
    AND p.user_id >= 0
GROUP BY p.user_id
HAVING count(*) >= <POST COUNT THRESHOLD>
1 Mi Piace

Sembra che funzionerebbe, ma sembra fallire quando il gruppo contro cui lo stai eseguendo è staff. Ho provato sia Staff che staff come nome del gruppo, e ho temporaneamente impostato il conteggio dei post e dei like a 1, e dice che non verranno concesse badge. Cosa sto sbagliando qui?

1 Mi Piace

hmm ho usato staff in minuscolo e ha funzionato per me. :thinking:

SELECT p.user_id, min(p.created_at) granted_at, MIN(p.id) post_id
FROM badge_posts p
JOIN topics t ON t.id = p.topic_id
WHERE (
        SELECT count(*)
        FROM post_actions pa
        WHERE pa.post_id = p.id
            AND post_action_type_id = (
                SELECT id FROM post_action_types WHERE name_key = 'like'
            ) AND pa.user_id IN (
                SELECT gu.user_id
                FROM group_users gu
                WHERE gu.group_id = ( SELECT id FROM groups WHERE name ILIKE 'staff' )
            )
    ) >= 1
    AND p.user_id >= 0
GROUP BY p.user_id
HAVING count(*) >= 1

Strano :face_with_spiral_eyes: Ancora non funziona per me. Proverò ad eseguirlo su altri gruppi per vedere se riesco a trovare il problema.

Modifica: Eseguito su un gruppo diverso e la query è ancora fallita. Non sono sicuro di quale sia il problema qui. Dipende per caso dai gruppi primari?

Modifica 2: Non funzionerebbe, staff non sembra poter essere impostato come gruppo primario.

Penso di sapere perché. Ci lavorerò per te dopo aver cenato. Ho comunque bisogno di fare pratica con SQL. Badge SQL è più restrittivo di postgres. Sono andato oltre la parte della sottoquery. :slight_smile:

3 Mi Piace

4 post sono stati divisi in un nuovo argomento: Query ‘Preview’ non funziona nella pagina badge SQL

Non mi sono ancora svegliato del tutto e mi rendo conto che le query sui badge richiedono un solido paio di tazze di tè prima di poterle affrontare appieno, ma ho parlato di recente con il bot riguardo a questo tipo di query e penso che utilizzare il vero post_action_code_id e il group_id siano meglio che utilizzare le query SELECT nidificate per trovare la stessa cosa.

1 Mi Piace

Ho fatto questo per ottenere le tabelle di schema necessarie per posts, posts_actions, group_users e groups

SELECT column_name, data_type, character_maximum_length
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = '<TABLE NAME>';

Poi ho usato questo per ottenere tutti gli ID dei gruppi:

SELECT name, id FROM groups ORDER BY name

Quindi ho incluso tutte le tabelle di schema necessarie e ho istruito Lola, ehm GPTbot, a usare l’ID effettivo di post_action_code e il codice group_id. Poi, dopo qualche discussione e alcune correzioni, siamo arrivati a questo. Ancora, sembra funzionare in Data Explorer, ma non riesco ancora a ottenere nulla dall’Anteprima Badge.

G = group_id
X = numero minimo di like
Y = numero minimo di post
SELECT pa.user_id, MIN(pa.post_id) as post_id, COUNT(pa.post_id) as post_count, COUNT(pa.id) as like_count, MAX(pa.created_at) as granted_at
FROM post_actions pa
JOIN group_users gu ON gu.user_id = pa.user_id
WHERE gu.group_id = G AND pa.post_action_type_id = 2
GROUP BY pa.user_id
HAVING COUNT(pa.post_id) >= Y AND COUNT(pa.id) >= X

sì, ho chiamato GP4bot Lola

Lo chiamo Bert. :slight_smile: Anche se abbiamo una relazione complicata.

Penso che un’altra limitazione a quel tipo di query sia l’uso di MIN(p.created_at) granted_at che mi dà la data del loro primo e non, diciamo, la data del loro decimo. Potrebbe essere cambiato in MAX, ma darebbe anche una data ‘sbagliata’ se la eseguissi su dati storici in cui ne avevano già più di 10.

Ci sto ancora pensando.

Ho avuto un po’ di successo usando ROW_NUMBER(), ma niente di concreto ancora.

2 Mi Piace

Sì, sono d’accordo. Qualcosa ancora non mi convince. Vado a letto. :sweat_smile:

3 Mi Piace

Mi sto divertendo con questo e mi sta aiutando a riapprendere SQL e come scrivere query migliori. Avere Lola / GPT4bot come assistente SQL è utile, ma devi guidarla e chiederle nel modo giusto. Ho cercato di capire come darle accesso alla maggior parte delle informazioni sulle tabelle dello schema in modo da non doverlo fare per ogni problema di query su cui lavoriamo. Fornire le informazioni sullo schema della tabella dà risultati molto migliori. Ho provato a darle un link agli schemi disponibili in core, ma questo l’ha solo fatta andare a cercare su Google.

Sono interessato a lavorare con lei quando saprò che il badge query previewer funziona. Ho bisogno di fare pratica con SQL e con le badge query. Tra l’altro, lei non può sistemarlo e mi fa ancora il mio tè Earl Grey non abbastanza caldo. Anche se la lezione di SQL di ieri sera è stata il miglior appuntamento che ho avuto da anni. :facepalm:

2 Mi Piace

Usando quella query, sembra che abbiamo avuto un problema strano. Sembra che sia stato assegnato solo allo staff e sono quasi certo che alcuni non staff soddisferebbero quel criterio. È qualcosa che ho rotto da qualche parte, o è un problema di query?

2 Mi Piace

Sì, so che c’è qualcosa che non va, ci lavorerò non appena la mia istanza verrà aggiornata con la correzione dell’anteprima.

2 Mi Piace

Solo per fare un reset, dato che penso che il botta e risposta mi abbia confuso. :slight_smile:

L’obiettivo è concedere un badge per un certo numero di post in tutte le categorie che sono stati apprezzati da @staff almeno una volta?

1 Mi Piace

Intendevo che fosse concesso agli utenti che hanno X numero di post con Y like da parte dello staff, in tutte le categorie. Nel mio caso, 10 post, 5 like.

3 Mi Piace

Dopo un confuso intoppo con alcuni Mi piace eliminati che hanno sballato i miei test, penso che questa sia una versione rivista di quella nell’OP che soddisfa i tuoi criteri: :slight_smile:

SELECT p.user_id, MAX(p.created_at) granted_at
FROM badge_posts p
WHERE (SELECT COUNT(*)
        FROM post_actions pa
        WHERE pa.post_id = p.id
         AND post_action_type_id = 2
         AND deleted_at IS NULL
         AND pa.user_id IN (SELECT gu.user_id FROM group_users gu WHERE gu.group_id = 3)
       ) >= 5
    AND p.user_id >= 0
GROUP BY p.user_id
HAVING COUNT(*) >= 10

Funziona sulla vista badge_posts, quindi conta solo i post dalle categorie pubbliche, cosa che potresti voler prendere in considerazione a seconda della configurazione del tuo forum/delle tue categorie. Inoltre, usare CURRENT_TIMESTAMP per granted_at è un’altra opzione, ma probabilmente è una questione di gusti.

2 Mi Piace