【问题标题】:How to conditionally count rows from another table WITHOUT USING A CORRELATED SUBQUERY?如何在不使用相关子查询的情况下有条件地计算另一个表中的行?
【发布时间】:2017-06-29 16:23:05
【问题描述】:

我有一个数据集,我必须有条件地计算表 B 中位于表 A 中两个日期之间的行。我必须在不使用 SELECT 子句中的相关子查询的情况下执行此操作,因为这是Netezza 不支持 - 文档:https://www.ibm.com/support/knowledgecenter/en/SSULQD_7.0.3/com.ibm.nz.dbu.doc/c_dbuser_correlated_subqueries_ntz_sql.html

表格背景:用户可以登录到站点(登录)。当他们登录时,他们可以采取行动,这些行动在(actions_taken)中。 所需的输出是 actions_taken action_date 和 lag_action_date 之间的行数。

在此处找到数据和尝试:http://rextester.com/NLDH13254

表格:actions_taken(添加了计算 - 请参阅 RexTester。)

| user_id | action_type   | action_date | lag_action_date | elapsed_days |
|---------|---------------|-------------|-----------------|--------------|
| 12345   | action_type_1 | 6/27/2017   | 3/3/2017        | 116          |
| 12345   | action_type_1 | 3/3/2017    | 2/28/2017       | 3            |
| 12345   | action_type_1 | 2/28/2017   | NULL            | NULL         |
| 12345   | action_type_2 | 3/6/2017    | 3/3/2017        | 3            |
| 12345   | action_type_2 | 3/3/2017    | 3/25/2016       | 343          |
| 12345   | action_type_2 | 3/25/2016   | NULL            | NULL         |
| 12345   | action_type_4 | 3/6/2017    | 3/3/2017        | 3            |
| 12345   | action_type_4 | 3/3/2017    | NULL            | NULL         |
| 99887   | action_type_1 | 4/1/2017    | 2/11/2017       | 49           |
| 99887   | action_type_1 | 2/11/2017   | 1/28/2017       | 14           |
| 99887   | action_type_1 | 1/28/2017   | NULL            | NULL         |

表格:登录

| user_id | login_date |
|---------|------------|
| 12345   | 6/27/2017  |
| 12345   | 6/26/2017  |
| 12345   | 3/7/2017   |
| 12345   | 3/6/2017   |
| 12345   | 3/3/2017   |
| 12345   | 3/2/2017   |
| 12345   | 3/1/2017   |
| 12345   | 2/28/2017  |
| 12345   | 2/27/2017  |
| 12345   | 2/25/2017  |
| 12345   | 3/25/2016  |
| 12345   | 3/23/2016  |
| 12345   | 3/20/2016  |
| 99887   | 6/27/2017  |
| 99887   | 6/26/2017  |
| 99887   | 6/24/2017  |
| 99887   | 4/2/2017   |
| 99887   | 4/1/2017   |
| 99887   | 3/30/2017  |
| 99887   | 3/8/2017   |
| 99887   | 3/6/2017   |
| 99887   | 3/3/2017   |
| 99887   | 3/2/2017   |
| 99887   | 2/28/2017  |
| 99887   | 2/11/2017  |
| 99887   | 1/28/2017  |
| 99887   | 1/26/2017  |
| 99887   | 5/28/2016  |

期望的输出:cnt_logins_between_action_dates 字段

| user_id | action_type   | action_date | lag_action_date | elapsed_days | cnt_logins_between_action_dates |
|---------|---------------|-------------|-----------------|--------------|---------------------------------|
| 12345   | action_type_1 | 6/27/2017   | 3/3/2017        | 116          | 5                               |
| 12345   | action_type_1 | 3/3/2017    | 2/28/2017       | 3            | 4                               |
| 12345   | action_type_1 | 2/28/2017   | NULL            | NULL         | 1                               |
| 12345   | action_type_2 | 3/6/2017    | 3/3/2017        | 3            | 2                               |
| 12345   | action_type_2 | 3/3/2017    | 3/25/2016       | 343          | 7                               |
| 12345   | action_type_2 | 3/25/2016   | NULL            | NULL         | 1                               |
| 12345   | action_type_4 | 3/6/2017    | 3/3/2017        | 3            | 2                               |
| 12345   | action_type_4 | 3/3/2017    | NULL            | NULL         | 1                               |
| 99887   | action_type_1 | 4/1/2017    | 2/11/2017       | 49           | 8                               |
| 99887   | action_type_1 | 2/11/2017   | 1/28/2017       | 14           | 2                               |
| 99887   | action_type_1 | 1/28/2017   | NULL            | NULL         | 1                               |

【问题讨论】:

  • 如果您使用的是 Netezza,为什么要添加 postgresql 标签?
  • 我理解 PostgreSQL 是 Netezza 解释的受支持语言。我认为 Netezza 是数据仓库硬件设备,通过它可以解释支持的 SQL 语法。不?由于我是一名简单的数据分析师,因此在这里非常感谢清晰。我要删除标签吗?
  • 不,一点也不。这是两个非常不同的数据库系统。两者都使用 SQL 作为他们的查询语言——也许这就是你所考虑的
  • @a_horse_with_no_name 。 . . Netezza 是基于 Postgres 的代码库构建的,许多数据库 (wiki.postgresql.org/wiki/PostgreSQL_derived_databases) 也是如此。 Netezza 代码库非常古老,因此与更新的 Postgres 版本没有太大关系。
  • 感谢各位的投入。关于如何实现所需输出的任何想法?谢谢

标签: sql netezza correlated-subquery aginity


【解决方案1】:

您不需要相关的子查询。使用登录表中的lagjoin 获取上一个日期,以计算日期之间的操作。

with prev_dates as (select at.*
                    ,coalesce(lag(action_date) over(partition by user_id,action_type order by action_date)
                              ,action_date) as lag_action_date 
                    from actions_taken at
                   )
select at.user_id,at.action_type,at.action_date,at.lag_action_date
,at.action_date-at.lag_action_date as elapsed_days
,count(*) as cnt
from prev_dates at
join login l on l.user_id=at.user_id and l.login_date<=at.action_date and l.login_date>=at.lag_action_date
group by at.user_id,at.action_type,at.action_date,at.lag_action_date
order by 1,2,3

【讨论】:

  • 太棒了!所以过程是:1.)创建一个 CTE,将空滞后值与操作日期合并 2.)内部连接 ​​tbl A 到 tbl B,以便所需的行现在位于单个表中 3.)计数(*)和组.非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
  • 2018-05-21
  • 1970-01-01
  • 2020-07-07
相关资源
最近更新 更多