繁体   English   中英

(Ms Access) Row_Number() 超过分区

[英](Ms Access) Row_Number() Over Partition

如何在 MS ACCESS 上使用过度分区转换 row_number() 函数? 我想要实现的是:

从这张表中:

ID  | EntryDate  
10  | 2016-10-10
10  | 2016-12-10
10  | 2016-12-31
10  | 2017-01-31
10  | 2017-03-31
11  | 2015-01-31
11  | 2017-01-31

对于此输出,仅显示每个 ID 的前 3 个最新:

ID  | EntryDate  
10  | 2016-12-31
10  | 2017-01-31
10  | 2017-03-31
11  | 2015-01-31
11  | 2017-01-31

在 SQL Server 上,我可以使用以下代码实现这一点:

select T.[ID],
   T.[AptEndDate],
from (
 select T.[ID],
        T.[AptEndDate],
        row_number() over(partition by T.[ID] order by T.[AptEndDate] desc) as rn
 from Table1 as T
 ) as T
where T.rn <= 3;

考虑一个可以在任何 RDBMS 中工作的计数相关子查询。

select T.[ID], T.[EntryDate]
from 
 (select sub.[ID],
         sub.[EntryDate],
         (select count(*) from Table1 c
          where c.ID = sub.ID 
          and c.[EntryDate] >= sub.[EntryDate]) as rn
 from Table1 as sub
 ) as T
where T.rn <= 3;

使用Top n可能更简单、更快捷 - 正如您自己提到的:

Select T.[ID], T.[EntryDate]
From Table1 As T
Where T.[EntryDate] In
    (Select Top 3 S.[EntryDate]
    From Table1 As S
    Where S.[ID] = T.[ID]
    Order By S.[EntryDate] Desc)
Order By T.[ID] Asc, T.[EntryDate] Asc

任何使用OVER子句的东西都被称为窗口函数。 不幸的是,MS Access 不支持窗口函数。在这种情况下,最简单的解决方案可能是回到 VBA 代码:(

Public Const tableName As String = "[TransactionalData$]"
Public Const parentId As String = "parentId"
Public Const elementId As String = "Id"
Public Const informationalField As String = "Label"
Sub TransactionalQuery(Optional ByVal Id As Integer = 0)
    Dim rs As New ADODB.Recordset, cn As New ADODB.Connection
    Dim sqlString As String
    ''' setup the connection to the current Worksheet --- this can be changed as needed for a different data source, this example is for EXCEL Worksheet
    cn.Open ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties='Excel 12.0 Macro;HDR=YES;IMEX=1'")
    '''' Alternate method for the query
    sqlString = "SELECT ParentId, Rank() OVER(PARTITION BY ParentId ORDER BY Label) , vlu.Id, vlu.Label FROM [TransactionalData$] var LEFT JOIN [TransactionalData$] vlu ON vlu.Id=var.ParentId"
    ''' will need to change the TableName (TransactionalData$]
    sqlString = "SELECT DISTINCT " & elementId & " FROM " & tableName & " WHERE " & parentId & " = " & Id
    rs.Open sqlString, cn, adOpenStatic, adLockReadOnly
    '' Start collecting the SQL UNIONs to run at the end
    sqlString = ""
    Do While Not rs.EOF
         '' Add current Element to the UNION
         sqlString = sqlString & "SELECT * FROM " & tableName & " WHERE " & elementId & " = " & rs.Fields(elementId) & " UNION " & vbCrLf
         '' Add all children element to the UNION
         sqlString = sqlString & subQuery(cn, rs.Fields(elementId))
         rs.MoveNext
    Loop
    rs.Close
    '''Debug.Print sqlString
    ''' Remove the extra UNION keyword at the end
    sqlString = Left(sqlString, Len(sqlString) - 8)
    ''' Exectue the built query
    rs.Open sqlString, cn, adOpenStatic, adLockReadOnly
    ''Do While Not rs.EOF
    ''   Debug.Print rs.Fields(elementId) & ", " & rs.Fields(informationalField)
    ''   rs.MoveNext
    ''Loop
End Sub
Function subQuery(cn As ADODB.Connection, Id As Integer) As String
    Dim sqlString As String
    Dim subSqlString As String, rs As New ADODB.Recordset
    '' Create a list of children for the current element
    sqlString = "SELECT DISTINCT " & elementId & " FROM " & tableName & "  WHERE " & parentId & " = " & Id
    rs.Open sqlString, cn, adOpenStatic, adLockReadOnly
    '' start the SQL for current elements children
    sqlString = ""
    Do While Not rs.EOF
        ''' add in the current element to the UNION
        sqlString = sqlString & "SELECT * FROM " & tableName & " WHERE Id = " & rs.Fields(elementId) & " UNION " & vbCrLf
        ''' recursively find additional children for the current element
        sqlString = sqlString & subQuery(cn, rs.Fields(elementId))
        rs.MoveNext
    Loop
    rs.Close
    ''' return the SQL for the current element and all its children
    subQuery = sqlString
End Function

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM