【问题标题】:Rank on each group without using derived table在不使用派生表的情况下对每个组进行排名
【发布时间】:2017-04-14 14:39:14
【问题描述】:
AccountNo           Account Name         Transaction time             Transaction Amount
A01                 Name 1               01-01-2016 04:00:00          5000
A01                 Name 1               01-01-2016 07:30:00          3500
A01                 Name 1               01-01-2016 09:30:00          3500
A01                 Name 1               01-01-2016 12:00:00          6500
A01                 Name 1               02-02-2016 06:00:00          4000
A01                 Name 1               01-02-2016 08:30:00          8000
A01                 Name 1               01-02-2016 09:30:00          8000
A02                 Name 2               05-01-2016 04:00:00          2000
A02                 Name 2               05-01-2016 07:30:00          8500
A02                 Name 2               08-02-2016 06:00:00          1000
A02                 Name 2               09-02-2016 08:30:00          9000

我需要一个不使用派生表的查询来获取每个帐户的最新交易记录。查询应支持OracleTERADATA。 使用派生表我可以解决它如下:

SELECT a.accountno, 
       a.account_name, 
       a.transaction_time, 
       a.transaction_amount 
FROM   acct_details a, 
       (SELECT accountno, 
               Max(transaction_time) AS Transaction_time 
        FROM   acct_details 
        GROUP  BY accountno) b 
WHERE  a.accountno = b.accountno 
   AND a.transaction_time = b.transaction_time;

感谢您的帮助!!

【问题讨论】:

    标签: sql oracle teradata


    【解决方案1】:

    为什么没有派生表?

    在 Teradata 中有 QUALIFY,但它不是标准 SQL:

    SELECT *
    FROM   acct_details 
    QUALIFY RANK() OVER (PARTITION BY accountno 
                         ORDER BY transaction_time DESC) = 1;
    

    在 Oracle 中,您需要一个派生表:

    SELECT a.accountno, 
           a.account_name, 
           a.transaction_time, 
           a.transaction_amount,
    FROM
     ( 
        SELECT a.accountno, 
               a.account_name, 
               a.transaction_time, 
               a.transaction_amount,
               RANK() OVER (PARTITION BY accountno 
                            ORDER BY transaction_time DESC) as rnk
        FROM   acct_details a
     ) a
    WHERE rnk = 1
    

    您也可以试试 Oracle 的 MAX/KEEP:

    SELECT a.accountno, 
           MAX (a.account_name) KEEP (DENSE_RANK FIRST ORDER BY a.transaction_time desc) , 
           MAX(a.transaction_time), 
           MAX (a.transaction_amount) KEEP (DENSE_RANK FIRST ORDER BY a.transaction_time desc)     FROM  acct_details a
    GROUP BY a.accountno
    

    【讨论】:

      【解决方案2】:

      你可以像这样使用内联视图来做到这一点:

      SELECT a.accountno, 
             a.account_name, 
             a.transaction_time, 
             a.transaction_amount 
      FROM   (SELECT accountno, 
                     account_name, 
                     transaction_time, 
                     transaction_amount, 
                     Max(transaction_time) OVER (PARTITION BY accountno) AS max_transaction_time 
              FROM   acct_details) a
      WHERE  a.transaction_time = a.max_transaction_time;
      

      这将适用于 Oracle,我认为它也应该适用于 Teradata。

      我在这里假设当您说要避免派生表时,您的意思是要避免将表连接到自身。

      【讨论】:

      • 两者都有相同的别名'a'?你确定吗??这应该会出错。
      • 内联视图 = 派生表
      • @TechBytes 哎呀,在发布我的答案之前,我忘记从 from 子句中删除该表。我现在已经删除了 - 谢谢!
      • @dnoeth 我添加了一条评论来解释我的假设。 OP 避免派生表是什么意思。
      • Ups,你是对的(修改后),对不起。但它仍然是一个派生表:-)
      【解决方案3】:

      试试这个查询:

      SELECT [交易时间],[账户名称],

      lead([Transaction time ],1,1) OVER (ORDER BY [Account Name])

      来自 [dbo].[acct_details]

      这应该对你有帮助

      【讨论】:

      • 这不能回答 OP 的问题。 OP 正在寻找每个帐号具有 max transaction_time 的行。您的查询甚至不是在寻找每个帐号的下一次交易时间,更不用说按交易时间排序了!所有的方括号是怎么回事?
      • @Boneist:这是微软的污染,所有这些方括号和等同于SQL = MS SQL :-)
      • @Boneist: 方括号后面有错吗,我只是在关注它们在数据库中的样子。
      • @Boneist:他已经明确提到他想要每个账户的最新交易
      • @Looking_for_answers 是的,他们做到了。但是,您的回答并没有给他们。而且,他们明确表示他们想要一个适用于 Oracle 或 Teradata 的答案。那些方括号绝对不在 Oracle SQL 语法中,我也愿意不在 Teradata 的语法中。
      猜你喜欢
      • 2017-05-07
      • 2016-09-03
      • 1970-01-01
      • 2014-06-25
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多