Ако приемем, че дефиницията на таблицата има това солидно ядро:
CREATE TABLE game_table (
user_id bigint NOT NULL
, date date NOT NULL -- date, not text!
, game_name text NOT NULL
, UNIQUE (date, game_name, user_id) -- !
);
И ако приемем, че имате предвид същия играч, който играе същата игра на следващия ден:
SELECT round(ct_day2 * 100.0 / ct_day1, 2) AS repeat_percentage
FROM (
SELECT count(*) AS ct_day1
, count(d2.user_id) AS ct_day2
FROM instant_game_sessions d1
LEFT JOIN instant_game_sessions d2 ON (d2.user_id, d2.game_name, d2.date)
= (d1.user_id, d1.game_name, d1.date + 1)
WHERE d1.date = '2021-01-07'
AND d1.game_name = 'Chess'
) sub;
UNIQUE
ограничението гарантира, че може да има само едно съвпадение на следващия ден. Така че count(*)
е правилният брой за ден 1 и count(d2.user_id)
за ден 2. Останалото е очевидно.
UNIQUE
ограничение (с имена на колони в този ред!) също предоставя идеалния индекс за заявката. Вижте:
Имайте предвид, че числовата константа 100.0
по подразбиране се задава числово автоматично, така че не е необходимо да добавяме изрично преобразуване на типа. Свързани: