hive中的cross join

yfwxisqw  于 2021-04-08  发布在  Hive
关注(0)|答案(2)|浏览(931)

我试图在运行下面的查询时创建一个新的列 "time_period"。如果给定的事务和参考表中最近的事务之间的日期差小于7天,那么就将其标记为 "recent "事务,否则就将其标记为 "old "事务。
然而,下面的查询在与交叉连接相关的子查询中产生了一个错误,错误是“cannot recognize input near 'select' '(''max'”

SELECT
    c.*
    FROM(
        SELECT
         a.acct_nb,
         a.txn_date,
         a.txn_amt,
         (CASE WHEN datediff(b.most_recent_txn,a.txn_date)<7 THEN 'recent' ELSE 'old' END) AS time_period
         FROM db.t1 a
         CROSS JOIN(
              SELECT max(txn_date) AS most_recent_txn --ERROR OCCURS HERE
              FROM db.t1 b)
        )c
        WHERE c.time_period='new';

是什么原因导致这个错误?

v6ylcynt

v6ylcynt1#

别名b应该应用于交叉连接的子查询,而不是应用于子查询中的表db.t1

SELECT c.*
FROM (
  SELECT a.acct_nb, a.txn_date, a.txn_amt,
         CASE WHEN datediff(b.most_recent_txn, a.txn_date) < 7 THEN 'recent' ELSE 'old' END AS time_period
  FROM db.t1 a
  CROSS JOIN (
    SELECT max(txn_date) AS most_recent_txn
    FROM db.t1 
  ) b
) c
WHERE c.time_period='new';

另外,你的CASE表达式中没有返回'new的分支,所以最后一个WHERE子句会过滤掉所有的行。

cs7cruho

cs7cruho2#

你不需要 "连接",你可以使用窗口函数。

SELECT 
    acct_nb,
    txn_date, 
    txn_amt,
    CASE WHEN DATEDIFF(MAX(txn_date) OVER(), txn_date) < 7 
        THEN 'recent' 
        ELSE 'old' 
    END AS time_period
FROM db.t1

如果你只需要过滤最近的交易,那么你可以使用一个子查询。

SELECT *
FROM (
    SELECT acct_nb, txn_date, txn_amt, MAX(txn_date) OVER() max_txn_date
    FROM db.t1
) t
WHERE DATEDIFF(MAX(txn_date) OVER(), txn_date) < 7

相关问题