【问题标题】:Use of window function and subquery in HiveHive 中窗口函数和子查询的使用
【发布时间】:2018-02-08 18:19:32
【问题描述】:

我有一张表格,其中一行代表一个订单。我正在尝试编写一个查询,该查询返回 2017 年的所有客户订单,在 2017 年 1 月下第二个订单之后。

初始代码如下所示:

SELECT
order_date
,cust_id 
,nth_booking
,total_bookings
FROM (SELECT order_date
,order_id
,COUNT (*) OVER (PARTITION BY cust_id ORDER BY order_date) AS nth_booking
,COUNT (*) OVER (PARTITION BY cust_id) AS total_bookings
FROM my.orders
WHERE order_date BETWEEN '2017-01-01' AND '2017-01-31') t1

这给出了以下输出,到目前为止一切顺利:

-------------------------------------------------------
| order_date | cust_id | nth_booking | total_bookings |
-------------------------------------------------------
| 2017-01-01 |   123   |       1     |       4        |
| 2017-01-02 |   123   |       2     |       4        |
| 2017-01-05 |   123   |       3     |       4        |
| 2017-09-27 |   123   |       4     |       4        |
| 2017-02-02 |   456   |       1     |       3        |
| 2017-11-16 |   456   |       2     |       3        |
| 2017-12-04 |   456   |       3     |       3        |
| 2017-01-17 |   678   |       1     |       5        |
| 2017-01-30 |   678   |       2     |       5        |
| 2017-02-31 |   678   |       3     |       5        |
| 2017-05-26 |   678   |       4     |       5        |
| 2017-09-18 |   678   |       5     |       5        |

但是,由于我只想检索必须在 2017 年 1 月发生的第二个订单之后的订单详细信息,因此我添加了一些附加条件,以便现在查询如下:

    SELECT
    order_date
    ,cust_id 
    ,nth_booking
    ,total_bookings
    FROM (SELECT order_date
    ,order_id
    ,COUNT (*) OVER (PARTITION BY cust_id ORDER BY order_date) AS nth_booking
    ,COUNT (*) OVER (PARTITION BY cust_id) AS total_bookings
    FROM my.orders
    WHERE order_date BETWEEN '2017-01-01' AND '2017-01-31') t1
  WHERE 
  nth_booking >= 2
  AND order_date BETWEEN '2017-01-01' AND '2017-01-31'

这显然是不正确的,我当然可以在查看下面的结果时明白为什么,其中 order_date 条件符合声明:

-------------------------------------------------------
| order_date | cust_id | nth_booking | total_bookings |
-------------------------------------------------------
| 2017-01-02 |   123   |       2     |       4        |
| 2017-01-05 |   123   |       3     |       4        |
| 2017-01-30 |   678   |       2     |       5        |

然而,我想要的更类似于此,第二个订单是在 2017 年 1 月下的,但我正在显示所有后续订单。

  -------------------------------------------------------
| order_date | cust_id | nth_booking | total_bookings |
-------------------------------------------------------
| 2017-01-01 |   123   |       2     |       4        |
| 2017-03-05 |   123   |       3     |       4        |
| 2017-09-27 |   123   |       4     |       4        |
| 2017-01-30 |   678   |       2     |       5        |
| 2017-02-31 |   678   |       3     |       5        |
| 2017-05-26 |   678   |       4     |       5        |
| 2017-09-18 |   678   |       5     |       5        |

我怎样才能看到这个视图?

我会很感激所提供的任何指导,并希望我提供了关于我的方法和工作的充分可重复的细节。

提前致谢

【问题讨论】:

    标签: hive subquery hiveql


    【解决方案1】:

    计算second_order_jan flagcust_id 并将其用于过滤:

    select
          order_date
         ,cust_id 
         ,nth_booking
         ,total_bookings 
    from
    ( --calculate second_order_jan flag for the cust_id
    select cust_id,
           order_date,
           order_id,
           nth_booking,
           total_bookings,
           max(case when month(order_date) = 1 and nth_booking=2 then 1 end) over (partition by cust_id) second_order_jan_flag  
    from 
    (
    SELECT cust_id,
         order_date
        ,order_id
        ,COUNT (*) OVER (PARTITION BY cust_id ORDER BY order_date) AS nth_booking
        ,COUNT (*) OVER (PARTITION BY cust_id) AS total_bookings
        FROM my.orders
        WHERE order_date BETWEEN '2017-01-01' AND '2017-01-31'
    ) t1
    ) t2 where second_order_jan_flag =1
           and nth_booking >= 2 --Filter only orders after second.
    

    【讨论】:

    • 非常感谢您的贡献,尽管这仍然没有返回我期望的结果,因为它似乎截断了 nth_booking 值。例如 - 我知道应该有 8 个 total_bookings 但 nth_booking 只返回 2、3、4 和 5 的行
    • 所以,在我最里面的查询中,我按日期过滤初始数据集,如您所见。我唯一能想到的是,如果 total_bookings 以某种方式通过 cust_id 评估终身预订,但我不知道这怎么可能。
    • @jimiclapton 请提供总共 8 次预订的数据示例
    • 解决了!我的外部 WHERE 子句中有一个导致问题的附加条件。你的回答正是我需要的。非常感谢。
    猜你喜欢
    • 2019-04-18
    • 1970-01-01
    • 2019-09-29
    • 1970-01-01
    • 1970-01-01
    • 2014-03-10
    • 2023-02-05
    • 2018-11-14
    • 1970-01-01
    相关资源
    最近更新 更多