【问题标题】:Cross Join across intermediary tables跨中间表交叉连接
【发布时间】:2017-08-16 22:53:54
【问题描述】:

我有一个包含 3 个表的数据库:队列时间段、用户和事件。

群组有很多用户,每个用户都有很多事件。群组也有与之相关的时间段。我想知道每个队列、每个时间段发生了多少事件。

如果有 2 张桌子,那么做 CROSS JOIN 会很容易,但是当有这张中间桌子时,我会被卡住。

这是数据库结构:

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

【问题讨论】:

    标签: postgresql cross-join


    【解决方案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_periodsusers 仅针对正确群组中的用户加入,然后仅针对特定时间段内的指定用户和事件加入events,然后按1 和2 分组以获得正确的偶数数

    【讨论】:

    • 啊!我从未见过between 语法。这就是我要找的!我试图用 CASE WHEN + SUM 来解决它,但它不起作用。谢谢:)
    • aww,这听起来很复杂...... sql 在日期方面还不错,而 between 只是 的语法糖
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-01
    • 1970-01-01
    相关资源
    最近更新 更多