sql >> Database teknologi >  >> RDS >> Mysql

Sum resultater af nogle få forespørgsler og find derefter top 5 i SQL

Til UNION de resulterende rækker af alle tre forespørgsler, og vælg derefter de 5 rækker med det højeste 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;

Manualen:

UNION ALL for at beholde dubletter.

At tilføje tæller for hver 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;

Den vanskelige del her er, at ikke alle event_id vil være til stede i alle tre basisforespørgsler. Så sørg for, at en JOIN mister ikke rækker fuldstændigt, og tilføjelser bliver ikke NULL .

Brug UNION ALL , ikke UNION . Du ønsker ikke at fjerne identiske rækker, du vil tilføje dem.

x er et tabelalias og en forkortelse for AS x . Det er påkrævet, for at en underforespørgsel skal have et navn. Kan være et hvilket som helst andet navn her.

SOL-funktionen FULL OUTER JOIN er ikke implementeret i MySQL (sidste gang jeg tjekkede), så du må nøjes med UNION . FULL OUTER JOIN ville forbinde alle tre basisforespørgsler uden at miste rækker.

Svar på opfølgende spørgsmål

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;

Eller for at bruge basistællingerne på flere måder:

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. Opret dynamisk PHP-objekt baseret på streng

  2. Dvale navnestrategi, ændring af tabelnavne

  3. Hvad er STATISTICS IO i SQL Server?

  4. Sådan opretter du en forespørgsel i Drupal 8