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 curtidas

Eu estava mexendo nisso e quase consegui fazer funcionar, mas não consegui aplicá-lo a todas as categorias da maneira que eu queria. Existe uma maneira simples de fazer isso?

2 curtidas

Olá @Firepup650 :slight_smile: talvez tente este. funcionou na minha instância.

<NOME DA CATEGORIA> = Nome da categoria sensível a maiúsculas e minúsculas (não slug)
<GRUPO> = Nome do Grupo (ex: Staff, Trust_level_0)
<CONTADOR MÍNIMO DE CURTIDAS> = número mínimo de curtidas que você deseja definir
<LIMITE DE CONTADOR DE POSTAGENS> = número mínimo de postagens
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 DA 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 DO GRUPO>' )
            )
    ) >= <CONTADOR MÍNIMO DE CURTIDAS>
    AND p.user_id >= 0
GROUP BY p.user_id
HAVING count(*) >= <LIMITE DE CONTADOR DE POSTAGENS>

para múltiplas categorias você pode fazer isso:

<NOMES DAS CATEGORIAS> = Nomes das categorias sensíveis a maiúsculas e minúsculas
<GRUPO> = Nome do Grupo (ex: Staff, Trust_level_0)
<CONTADOR MÍNIMO DE CURTIDAS> = número mínimo de curtidas que você deseja definir
<LIMITE DE CONTADOR DE POSTAGENS> = número mínimo de postagens
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 DA CATEGORIA 1>', '<NOME DA CATEGORIA 2>', '<NOME DA 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 '<GRUPO>' )
            )
    ) >= <CONTADOR MÍNIMO DE CURTIDAS>
    AND p.user_id >= 0
GROUP BY p.user_id
HAVING count(*) >= <LIMITE DE CONTADOR DE POSTAGENS>
1 curtida

Olá @Lilly!

Ambas parecem ótimas consultas, mas eu queria apenas executar a consulta em todas as categorias, se possível. Quando tentei, fiquei recebendo erros sobre uma subconsulta retornando várias linhas, então vim perguntar aqui sobre isso.

1 curtida

Você quer dizer que deseja a mesma consulta para todas as categorias?

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 curtida

Isso parece que funcionaria, mas falha quando o grupo contra o qual você está executando é staff. Tentei Staff e staff como nome do grupo, e temporariamente defini a contagem de posts e curtidas para 1, e diz que nenhum distintivo seria concedido. O que estou fazendo de errado aqui?

1 curtida

hmm usei minúsculas staff e funcionou para mim. :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

Estranho :face_with_spiral_eyes: Ainda não funciona para mim. Tentarei executá-lo em alguns outros grupos para ver se consigo encontrar o problema.

Editar: Executei em um grupo diferente e a consulta ainda falhou. Não tenho certeza de qual seria o problema aqui. Depende de grupos primários por acaso?

Editar 2: Isso não funcionaria, staff não parece ter permissão para ser definido como um grupo primário.

Acho que sei o motivo. Vou trabalhar nisso para você depois de jantar. Preciso de prática em SQL de qualquer maneira. SQL de distintivo é mais restritivo que postgres. Passei da parte da subconsulta. :slight_smile:

3 curtidas

4 posts foram divididos em um novo tópico: Consulta ‘Visualizar’ não funciona na página de selo SQL

Ainda não acordei completamente, e acho que as consultas de distintivos precisam de duas xícaras de chá para serem totalmente resolvidas, mas tenho conversado com o bot recentemente sobre esse tipo de consulta e acho que usar o post_action_code_id e o group_id reais é melhor do que usar as consultas SELECT aninhadas para encontrar a mesma coisa.

1 curtida

Eu fiz isso para obter as tabelas de esquema necessárias para posts, posts_actions, group_users e groups

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

Em seguida, usei isso para obter todos os IDs de grupo:

SELECT name, id FROM groups ORDER BY name

Então incluí todas as tabelas de esquema necessárias e instruí Lola, er GPTbot, a usar o ID real de post_action_code e o código group_id. Então, após alguma discussão e correções. Chegamos a isso. Novamente, parece funcionar no Explorador de Dados, mas ainda não consigo obter nada dele no Visualizador de Emblemas.

G = group_id
X = número mínimo de curtidas
Y = número mínimo de posts
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

sim, eu chamei GP4bot de Lola

Eu chamo o meu de Bert. :slight_smile: Embora tenhamos um relacionamento complicado.

Acho que outra limitação para esse tipo de consulta é usar MIN(p.created_at) granted_at que me dá a data da primeira e não, digamos, a data da décima. Poderia ser alterado para MAX, mas isso também daria uma data ‘errada’ se você executasse contra dados históricos onde eles já tinham mais de 10.

Ainda estou pensando nisso.

Tive algum sucesso usando ROW_NUMBER(), mas nada concreto ainda.

2 curtidas

sim, concordo. algo ainda não parece certo. vou para a cama. :sweat_smile:

3 curtidas

Estou me divertindo com isso e está me ajudando a reaprender SQL e como escrever consultas melhores. Ter Lola / GPT4bot como assistente SQL é útil, mas você tem que guiá-la e perguntar da maneira certa. Estou tentando descobrir maneiras de dar a ela acesso à maior parte das informações das tabelas do esquema para que eu não precise fazer isso para cada problema de consulta em que trabalhamos. Fornecer as informações do esquema da tabela dá resultados muito melhores. Tentei dar a ela um link para os esquemas disponíveis no core, mas isso apenas a fez perder tempo no Google.

Estou interessado em trabalhar com ela quando souber que o previewer de consulta de badge está funcionando. Preciso praticar SQL e fazer consultas de badge. Aliás, ela não consegue consertar e ainda faz meu chá Earl Grey não ficar quente o suficiente. Embora a aula de SQL de ontem à noite tenha sido o melhor encontro que tive em anos. :facepalm:

2 curtidas

Com essa consulta, parece que tivemos um problema estranho. Parece que foi concedido apenas à equipe, e tenho quase certeza de que alguns não funcionários atenderiam a esse critério. Isso é algo que quebrei em algum lugar, ou é um problema de consulta?

2 curtidas

Sim, eu sei que algo está errado, vou trabalhar nisso assim que minha instância for atualizada com a correção do previewer.

2 curtidas

Só para ter um recomeço, pois acho que a troca de mensagens me confundiu. :slight_smile:

O objetivo é conceder um selo para uma certa quantidade de posts em todas as categorias que foram curtidas por @staff pelo menos uma vez?

1 curtida

Eu pretendia que fosse concedido a usuários que tivessem X número de posts com Y curtidas pela equipe, em todas as categorias. No meu caso, 10 posts, 5 curtidas.

3 curtidas

Depois de um pequeno contratempo com alguns Likes excluídos que atrapalharam meus testes, acho que esta é uma versão revisada daquela no OP que atende aos seus critérios: :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

Ele funciona a partir da visualização badge_posts, então ele só conta postagens de categorias públicas, o que você pode querer levar em consideração dependendo da configuração do seu fórum/categoria. Além disso, usar CURRENT_TIMESTAMP para granted_at é outra opção, mas provavelmente é uma questão de gosto.

2 curtidas