2017-08-16 12 views
0

私は3つのテーブルを持つデータベースを持っています:コホートの期間、ユーザー、およびイベント。中間テーブル間でのクロス参加

コホートには多くのユーザーがおり、各ユーザーには多くのイベントがあります。コホートにも時間があります。私は各コホートごとに、どのくらい多くのイベントが発生したかを知りたいと思います。

2つのテーブルがある場合、CROSS JOINを実行するのは簡単ですが、この中間テーブルがある場合は固執しています。

ここでDB構造です:

create table time_periods (
    cohort_name varchar, 
    period_name varchar, 
    start_time timestamp, 
    end_time timestamp); 

create table users (
    cohort_name varchar, 
    user_name varchar 
); 

create table events (
    user_name varchar, 
    ts timestamp); 

insert into time_periods values 
('cohort1', 'first', '2017-01-01', '2017-01-10'), 
('cohort1', 'second', '2017-01-10', '2017-01-20'), 
('cohort2', 'first', '2017-01-15', '2017-01-20'); 

insert into users values 
    ('cohort1', 'alice'), 
    ('cohort2', 'bob'); 

insert into events values 
('alice', '2017-01-07'), 
('alice', '2017-01-17'), 
('bob', '2017-01-18'); 

これは私の知る限りは、SQLで得ることができるようです - 参加トリプルクロスをやってますが、それは正しくない - 結果は6つのイベントで、それだけであるべきとき行ごとに1つ。ここで

select 
    time_periods.cohort_name, 
    period_name, 
    count(ts) 
from time_periods, users, events 
group by 1, 2 
order by time_periods.cohort_name 

はSQLFiddleです:

http://sqlfiddle.com/#!17/b141e/2

答えて

1

あなたは私はあなたのデータを理解していれば、正しくあなたはこのような何かをしたいあなたは、テーブル に参加する列に指定する必要があります。

select 
    tp.cohort_name, 
    tp.period_name, 
    count(*) 
from time_periods tp 
inner join users u on tp.cohort_name = u.cohort_name 
inner join events e on u.user_name = e.user_name and e.ts between tp.start_time and tp.end_time 
group by 1, 2 
order by tp.cohort_name 

ここでは、time_periodsからusersへの参加は、正しいコホートのユーザーのみです特定の期間内に指定されたユーザーとイベントについてのみeventsに参加し、次に1と2でグループ化して正しい偶数を取得します

+0

Ah!私は構文の間に '間'を見たことがない。それは私が探していたものです!私はCASE WHEN + SUMで解決しようとしていましたが、うまくいきませんでした。ありがとう:) – LittleBobbyTables

+0

aww、それは複雑に聞こえます... SQLは日付で半分悪くはないとの間には user3012759

関連する問題