DENSE_RANK() OVER (Order by UniqueIdentifer) 问题

Posted

技术标签:

【中文标题】DENSE_RANK() OVER (Order by UniqueIdentifer) 问题【英文标题】:DENSE_RANK() OVER (Order by UniqueIdentifer) issue 【发布时间】:2015-03-27 08:04:25 【问题描述】:

我正在努力让 DENSE_RANK 做我想做的事。

基本上是根据唯一标识符创建唯一的发票编号,但需要根据发票的日期/时间顺序上去。

例如我需要:

InvoiceNo                  TxnId                     TxnDate
    1       6C952E91-B888-4244-9079-14FBECAE0BA2    01/01/2014 00:01
    1       6C952E91-B888-4244-9079-14FBECAE0BA2    01/01/2014 00:02
    1       6C952E91-B888-4244-9079-14FBECAE0BA2    01/01/2014 00:03
    1       6C952E91-B888-4244-9079-14FBECAE0BA2    01/01/2014 00:04
    1       6C952E91-B888-4244-9079-14FBECAE0BA2    01/01/2014 00:05
    1       6C952E91-B888-4244-9079-14FBECAE0BA2    01/01/2014 00:06
    1       6C952E91-B888-4244-9079-14FBECAE0BA2    01/01/2014 00:07
    1       6C952E91-B888-4244-9079-14FBECAE0BA2    02/01/2014 00:08
    2       8A5BCC36-8A70-4BE1-9FAB-A33BDD5BB78F    02/02/2014 00:09
    2       8A5BCC36-8A70-4BE1-9FAB-A33BDD5BB78F    02/02/2014 00:09
    3       83168B53-1647-4EB9-AF17-0B285EAA69B4    03/03/2014 00:10
    3       83168B53-1647-4EB9-AF17-0B285EAA69B4    03/03/2014 00:20
    3       83168B53-1647-4EB9-AF17-0B285EAA69B4    03/03/2014 00:21
    3       83168B53-1647-4EB9-AF17-0B285EAA69B4    03/03/2014 00:23

但是当我使用 DENSE_RANK OVER(按 TxnId 排序)时得到的是:

InvoiceNo       TxnId                                 TxnDate
    1       6C952E91-B888-4244-9079-14FBECAE0BA2    01/01/2014 00:02
    1       6C952E91-B888-4244-9079-14FBECAE0BA2    01/01/2014 00:01
    1       6C952E91-B888-4244-9079-14FBECAE0BA2    01/01/2014 00:03
    1       6C952E91-B888-4244-9079-14FBECAE0BA2    01/01/2014 00:04
    1       6C952E91-B888-4244-9079-14FBECAE0BA2    01/01/2014 00:06
    1       6C952E91-B888-4244-9079-14FBECAE0BA2    01/01/2014 00:05
    1       6C952E91-B888-4244-9079-14FBECAE0BA2    02/01/2014 00:08
    1       6C952E91-B888-4244-9079-14FBECAE0BA2    01/01/2014 00:07
    2       83168B53-1647-4EB9-AF17-0B285EAA69B4    03/03/2014 00:10
    2       83168B53-1647-4EB9-AF17-0B285EAA69B4    03/03/2014 00:21
    2       83168B53-1647-4EB9-AF17-0B285EAA69B4    03/03/2014 00:20
    2       83168B53-1647-4EB9-AF17-0B285EAA69B4    03/03/2014 00:23
    3       8A5BCC36-8A70-4BE1-9FAB-A33BDD5BB78F    02/02/2014 00:09
    3       8A5BCC36-8A70-4BE1-9FAB-A33BDD5BB78F    02/02/2014 00:09

如果我执行 DENSE_RANK OVER(TxnId,TxnDate),那将是一团糟,也不符合我的要求。

有什么想法吗?我什至使用 write 功能来做到这一点?任何帮助表示赞赏:)

【问题讨论】:

你想要ROW_NUMBER而不是DENSE_RANK吗? 不,无论发票如何,Row_Number 都会为发票编号执行 1、2、3、4、5、6、7,我需要每个 TxnId 1 个唯一发票编号,但按日期排序。 不,你可以使用ROW_NUMBER() OVER (Partition By TxnId Order by TxnDate) 我就是这么做的。然后根据有多少相同 TxnId 的实例进行计数。也就是说,如果有 3 个实例具有相同的事务 ID,则每个实例都有一个唯一的编号,这是不正确的。它需要 TxnId 唯一,因此 1 TxnId = 1 Invoice Number。 【参考方案1】:

我想你想要:

select dense_rank() over (order by txnid, txndate)

具有相同交易 ID 日期的所有事物都将具有相同的值。

编辑:

如果您需要提取日期,那么这取决于数据库。它看起来像这样。对于甲骨文:

select dense_rank() over (order by txnid, trunc(txndate))

对于 Postgres:

select dense_rank() over (order by txnid, date_trunc('day', txndate))

对于 SQL Server:

select dense_rank() over (order by txnid, cast(txndate as date))

编辑二:

您希望交易按最早日期排序。获取最早的日期,然后执行dense_rank()

select dense_rank() over (order by txnmindate, txnid)
from (select t.*, min(txndate) over (partition by txnid) as txnmindate
      from table t
     ) t

【讨论】:

No Dense_Rank() over (Order by TxnId,TxnDate) 将不起作用,因为每行 TxnId 的日期不同。我将编辑原件以显示这一点。 似乎根本没有任何区别,如果有一个事务滚动到第二天它也不会工作。顺便使用 SQL Server。 @Adam'Yoko'Chapman 。 . .这回答了您提出的问题。如果您有其他问题,例如跨越多天的交易以及确定它们是否获得新发票 ID 的规则,请提出另一个问题并提供适当的详细信息。 在第一个 TxnId 上指定的示例跨越了多天,但可能不太清楚。

以上是关于DENSE_RANK() OVER (Order by UniqueIdentifer) 问题的主要内容,如果未能解决你的问题,请参考以下文章

oracle RANK() dense_rank()

sql over表示啥意思

over在SQL里就啥意思

Oracle over函数

SQL over的作用及用法

MySQL - 排序函数 Rank() Over()Dense_rank() Over()Row_number() Over()