sql >> Database >  >> RDS >> Mysql

Tel de resultaten van een paar zoekopdrachten op en vind dan de top 5 in SQL

Naar UNION de resulterende rijen van alle drie de zoekopdrachten en kies vervolgens de 5 rijen met het hoogste amount :

(SELECT event_id, count(*) AS amount
FROM   pageview 
GROUP  BY event_id
ORDER  BY pageviews DESC, rand()
LIMIT  1000)

UNION ALL
(SELECT event_id, count(*)
FROM   upvote
GROUP  BY event_id
ORDER  BY upvotes DESC, rand()
LIMIT  1000)

UNION ALL
(SELECT event_id, count(*)
FROM   attending
GROUP  BY event_id
ORDER  BY attendants DESC, rand()
LIMIT  1000)

ORDER  BY 2 DESC
LIMIT  5;

De handleiding:

UNION ALL om duplicaten te bewaren.

Om de tellingen toe te voegen voor elke event_id :

SELECT event_id, sum(amount) AS total
FROM (
   (SELECT event_id, count(*) AS amount
    FROM   pageview 
    GROUP  BY event_id
    ORDER  BY pageviews DESC, rand()
    LIMIT  1000)
    
    UNION ALL
    (SELECT event_id, count(*)
    FROM   upvote
    GROUP  BY event_id
    ORDER  BY upvotes DESC, rand()
    LIMIT  1000)
    
    UNION ALL
    (SELECT event_id, count(*)
    FROM   attending
    GROUP  BY event_id
    ORDER  BY attendants DESC, rand()
    LIMIT  1000)
    ) x
GROUP  BY 1
ORDER  BY sum(amount) DESC
LIMIT  5;

Het lastige hier is dat niet elke event_id zal aanwezig zijn in alle drie de basisquery's. Zorg er dus voor dat een JOIN verliest rijen niet volledig en toevoegingen worden niet NULL .

Gebruik UNION ALL , niet UNION . U wilt identieke rijen niet verwijderen, u wilt ze optellen.

x is een tabelalias en afkorting voor AS x . Een subquery moet een naam hebben. Kan hier elke andere naam zijn.

De SOL-functie FULL OUTER JOIN is niet geïmplementeerd in MySQL (laatste keer dat ik het controleerde), dus je moet het doen met UNION . FULL OUTER JOIN zou deelnemen aan alle drie de basisquery's zonder rijen te verliezen.

Antwoord op vervolgvraag

SELECT event_id, sum(amount) AS total
FROM (
   (SELECT event_id, count(*) / 100 AS amount
    FROM   pageview ... )
    
    UNION ALL
    (SELECT event_id, count(*) * 5 
    FROM   upvote ... )
    
    UNION ALL
    (SELECT event_id, count(*) * 10
    FROM   attending ... )
    ) x
GROUP  BY 1
ORDER  BY  sum(amount) DESC
LIMIT  5;

Of, om de basistellingen op meerdere manieren te gebruiken:

SELECT event_id
      ,sum(CASE source
              WHEN 'p' THEN amount / 100
              WHEN 'u' THEN amount * 5
              WHEN 'a' THEN amount * 10
              ELSE 0
           END)  AS total
FROM (
   (SELECT event_id, 'p'::text AS source, count(*) AS amount
    FROM   pageview ... )
    
    UNION ALL
    (SELECT event_id, 'u'::text, count(*)
    FROM   upvote ... )
    
    UNION ALL
    (SELECT event_id, 'a'::text, count(*)
    FROM   attending ... )
    ) x
GROUP  BY 1
ORDER  BY 2 DESC
LIMIT  5;



  1. hoe emuleren insert negeer en bij dubbele sleutel update (sql merge) met postgresql?

  2. Komma's verwijderen met php uit mysql

  3. mysql match tegen ~ voorbeeld

  4. ColdFusion - Arabische/Perzische tekens invoegen in mysql