如何有条件地计算另一个表中的行而不使用相关的子查询?

时间:2017-06-29 16:23:06

标签: sql netezza correlated-subquery aginity

我有一个数据集,我必须有条件地计算表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。)

+products('assets/img/favorite_four.jpg', 'Machiato Coffee', '5')(data-filter='breakfast')

表:登录

| 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         |

渴望的输出:cnt_logins_between_action_dates字段

| 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  |

1 个答案:

答案 0 :(得分:2)

您不需要相关的子查询。使用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
相关问题