SQL:追加本月的记录数 column/field

SQL: Appending number of records from this month as a column/field

我正在使用 HiveQL 尝试查询 Hadoop。我的问题是这样的。

假设我有一个这样的查询(结果 table):

SELECT CustomerID, PurchaseID, DateOfPurchase
FROM MyTableName;

+------------+------------+----------------+
| CustomerID | PurchaseID | DateOfPurchase |
+------------+------------+----------------+
|        101 |        501 | 2014-01-01     |
|        101 |        502 | 2014-01-15     |
|        101 |        503 | 2014-01-20     |
|        101 |        504 | 2015-01-19     |
|        101 |        505 | 2015-08-25     |
|        102 |        506 | 2014-01-02     |
|        102 |        507 | 2014-01-03     |
|        103 |        508 | 2016-05-05     |
+------------+------------+----------------+

我想添加另一列,表示客户每月的订单数,与每一行中的日期相对应。这是我对结果 table:

的想法
+------------+------------+----------------+--------------------+
| CustomerID | PurchaseID | DateOfPurchase | PurchasesThisMonth |
+------------+------------+----------------+--------------------+
|        101 |        501 | 2014-01-01     |                  3 |
|        101 |        502 | 2014-01-15     |                  3 |
|        101 |        503 | 2014-01-20     |                  3 |
|        101 |        504 | 2015-01-19     |                  1 |
|        101 |        505 | 2015-08-25     |                  1 |
|        102 |        506 | 2014-01-02     |                  2 |
|        102 |        507 | 2014-01-03     |                  2 |
|        103 |        508 | 2016-05-05     |                  1 |
+------------+------------+----------------+--------------------+

也就是说,对于每一行,PurchasesThisMonth 列表示该客户在该月购买了多少商品。客户 101 在 2014 年 1 月进行了 3 次购买,因此 2014 年 1 月的每一行在 PurchasesThisMonth 中都有一个 3。

我能够在同一个 table. 的子查询上使用 INNER JOIN 来实现它,但是考虑到我的数据集相当大,这需要相当长的时间大。但是,是否有 better/faster 方法来做到这一点?

这是我的暴力破解方法。

SELECT CustomerID, PurchaseID, DateOfPurchase, Sub.PurchasesThisMonth
FROM MyTableName
INNER JOIN (
    SELECT 
    CustomerID, 
    COUNT(Inner.PurchaseID) as PurchasesThisMonth
    MONTH(Inner.DateOfPurchase) as month, 
    YEAR(Inner.DateOfPurchase) as year

    FROM MyTableName Inner
    GROUP BY Inner.CustomerID, 
             MONTH(Inner.DateOfPurchase), 
             YEAR(Inner.DateOfPurchase)
) Sub
ON CustomerID=Sub.CustomerID AND
   MONTH(DateOfPurchase)=Sub.month AND
   YEAR(DateOfPurchase)=Sub.year

此查询对完全相同的 table 进行了整个子查询。这是必要的吗?如果不是,这里的最佳做法是什么?

谢谢!

我想你可以使用 window 函数 count() over()

SELECT CustomerID, PurchaseID, DateOfPurchase
,count(*) over(partition by
               customerid,
               MONTH(DateOfPurchase), 
               YEAR(DateOfPurchase) order by customerid)
FROM MyTableName;