t-mart
t-mart

Reputation: 981

Divide Matching Rows in Table by Matching Rows in Other Table

My BigQuery database models an online game. It has tables for:

I'm trying to determine the overall win rate for raids that occurred in a specific channel. The win rate is the total number of win rows divided by the total number of entry rows if the raid for the win/entry raid is channel C. Something like:

Formula

The closest I've come is by running 2 sub-select queries, but I feel there must be a better way, where I don't have to repeat myself and run essentially 3 queries total.

SELECT
  (
  SELECT
    COUNT(*)
  FROM
    win
  JOIN
    raid
  ON
    win.raid_id = raid.id
  WHERE
    raid.channel = "#antonidas") / (
  SELECT
    COUNT(*)
  FROM
    entry
  JOIN
    raid
  ON
    entry.raid_id = raid.id
  WHERE
    raid.channel = "#antonidas") AS `win_rate`

Upvotes: 0

Views: 30

Answers (1)

Nick
Nick

Reputation: 147166

This query should give you your desired results. It LEFT JOINs raid to entry and win and then counts the number of distinct rows in each of those tables to determine the number of entries and wins per channel:

SELECT r.channel,
       COUNT(DISTINCT r.id) AS raids,
       COUNT(DISTINCT w.raid_id) AS wins, 
       COUNT(DISTINCT e.raid_id) AS entries,
       CAST(COUNT(DISTINCT w.raid_id) AS FLOAT) / COUNT(DISTINCT e.raid_id) AS win_rate
FROM raid r
LEFT JOIN entry e ON e.raid_id = r.id
LEFT JOIN win w ON w.raid_id = r.id
GROUP BY r.channel

Output (for your sample data):

channel     raids   wins    entries     win_rate
#antonidas  4       2       4           0.5
#anvilmar   1       1       1           1

Demo on dbfiddle

Note you can add WHERE channel = ... before the GROUP BY to restrict results to one particular channel. Also you can remove any columns you don't actually need, I put them all in to demonstrate the numbers being computed from your sample data.

Upvotes: 1

Related Questions