如何联接条件不相等的表?

时间:2019-04-27 09:25:37

标签: sql postgresql greatest-n-per-group

我正在尝试向所有用户查询其首次成功安装的应用程序以及应用程序版本详细信息。

因此,我尝试查询用户的首次成功安装,然后将installed_date与install_date之前的最新应用程序版本进行比较。

js

上面的查询返回所有首次成功安装的用户。

当他们首次成功安装应用程序时,如何找到他们安装了哪个版本?

我的表格如下所述:

tsc -b

3 个答案:

答案 0 :(得分:1)

我不相信该查询能满足您的要求:

SELECT DISTINCT user_id, installed_time
WHERE state=SUCCESSFUL
FROM installation
ORDER BY ASC;

除了明显的语法错误外,多次安装的用户还会出现多次。那可能就是您想要的,但这不是第一次成功安装。

我认为查询应该是:

SELECT i.user_id, MIN(i.installed_time)
FROM installation i
WHERE i.state = 'SUCCESSFUL'
GROUP BY i.user_id;

或者,如果要表中的所有列,请使用DISTINCT ON

SELECT DISTINCT ON (i.user_id) i.*
FROM installation i
WHERE i.state = 'SUCCESSFUL'
ORDER BY i.user_id, i.installation_time

如果您当时想要有效的版本,则有多种选择。在Postgres中,我建议使用横向联接:

SELECT i.*, v.*
FROM (SELECT i.user_id, MIN(i.installed_time) as installed_time
      FROM installation i
      WHERE i.state = 'SUCCESSFUL'
      GROUP BY i.user_id
     ) i LEFT JOIN LATERAL
     (SELECT v.*
      FROM versions v
      WHERE v.release_date <= i.installed_time
      ORDER BY v.release_date DESC
      FETCH FIRST 1 ROW ONLY
     ) v
     ON 1=1;

答案 1 :(得分:0)

您可以使用窗口功能轻松实现此目标。窗口功能对于“高级” SQL脚本非常有用。

通常在软件中,有很多方法可以做到这一点,这是使用FIRST_VALUE()的简单方法。

SELECT DISTINCT
  i.user_id,
  FIRST_VALUE(v.version_id) OVER(
    PARTITION BY i.user_id
    ORDER BY v.released_date DESC
  ) AS first_version_installed
FROM installation AS i
INNER JOIN version AS v
  ON i.installation_date >= v.released_date
WHERE i.state = 'SUCCESSFULL'

进一步阅读:

答案 2 :(得分:0)

您可以将distinct on (...)order by一起使用以获取最早安装的版本。 distinct on表达式必须与最左边的order by表达式匹配。

select  distinct on (i.user_id)
,       i.user_id
,       i.installed_date 
,       v.release_code
from    installation i
join    version v
on      v.release_date <= i.installed_date
where   i.state = 'SUCCESSFUL'
order by
        i.user_id              -- Required for distinct on, see note above
,       i.installed_date desc  -- First installation per user
,       v.release_date         -- Latest version available at installation date