【问题标题】:SQL Server: create an incremental counter for records in the same year?SQL Server:为同一年的记录创建增量计数器?
【发布时间】:2020-02-29 04:37:59
【问题描述】:

我有一个包含以下列的表格:

EmployeeID
EventDate (mm/dd/yyyy)
Event

我需要创建一个新列,该列将按年份计算每个事件,并以##-yyyy 格式插入一个值。比如我想创建一个类似 Counter 的文件:

EmployeeID      EventDate   Event   Counter
------------------------------------------
  001           01/05/2018    A     01-2018
  002           12/12/2018    A     01-2018
  001           03/01/2019    A     01-2019
  001           04/05/2019    A     02-2019
  002           05/05/2019    A     01-2018

我不需要按事件或事件类型来计算。我只需要为一年中的每个事件包含一个计数器,并在每个事件发生的日期之前递增。因此,2019 年 1 月的事件的数量将低于 2019 年 6 月的事件。

【问题讨论】:

  • MS SQL 可能是 Access 或 SQL Server,而您的标签并不清楚。请决定并删除不正确的标签

标签: sql sql-server ms-access


【解决方案1】:

如果这是 SQL 服务器:

SELECT
   ...,
   CONCAT(
     FORMAT(
       ROW_NUMBER() OVER(PARTITION BY employeeid, YEAR(eventdate) ORDER BY eventdate ASC), 
       'D2'
     ), 
     '-', 
     YEAR(eventdate)
   ) as counter
FROM ...

ROW_NUMBER() 将从 1 开始增加一个计数器,该计数器会重新启动每个不同的员工/年。我们将其格式化为以 0 开头,然后附加连字符和年份

如果您希望同一个月内的所有事件都具有相同的编号,请考虑使用 DENSE_RANK() OVER(PARTITION BY employeeid, YEAR(eventdate) ORDER BY MONTH(eventdate)) 而不是行号。

【讨论】:

    【解决方案2】:

    与@Caius Jard 的回答略有不同,这几乎是正确的。

    SELECT 
        EmployeeID,
        EventDate,
        [Event],
        FORMAT(ROW_NUMBER() OVER(PARTITION BY DATEPART(YEAR, EventDate), EmployeeID, [Event] ORDER BY EventDate ASC) , 'D2') 
        + '-' 
        + FORMAT(DATEPART(YEAR, EventDate), 'D4') AS Counter
    FROM YOUR_TABLE
    

    【讨论】:

      【解决方案3】:

      在 Access 中,您将需要一个自定义函数,例如我的 RowNumber,它允许分组:

      ' Builds consecutive row numbers in a select, append, or create query
      ' with the option of a initial automatic reset.
      ' Optionally, a grouping key can be passed to reset the row count
      ' for every group key.
      '
      ' 2018-08-23. Gustav Brock, Cactus Data ApS, CPH.
      '
      Public Function RowNumber( _
          ByVal Key As String, _
          Optional ByVal GroupKey As String, _
          Optional ByVal Reset As Boolean) _
          As Long
      
          ' Uncommon character string to assemble GroupKey and Key as a compound key.
          Const KeySeparator      As String = "¤§¤"
          ' Expected error codes to accept.
          Const CannotAddKey      As Long = 457
          Const CannotRemoveKey   As Long = 5
      
          Static Keys             As New Collection
          Static GroupKeys        As New Collection
          Dim Count               As Long
          Dim CompoundKey         As String
      
          On Error GoTo Err_RowNumber
      
          If Reset = True Then
              ' Erase the collection of keys and group key counts.
              Set Keys = Nothing
              Set GroupKeys = Nothing
          Else
              ' Create a compound key to uniquely identify GroupKey and its Key.
              ' Note: If GroupKey is not used, only one element will be added.
              CompoundKey = GroupKey & KeySeparator & Key
              Count = Keys(CompoundKey)
      
              If Count = 0 Then
                  ' This record has not been enumerated.
                  '
                  ' Will either fail if the group key is new, leaving Count as zero,
                  ' or retrieve the count of already enumerated records with this group key.
                  Count = GroupKeys(GroupKey) + 1
                  If Count > 0 Then
                      ' The group key has been recorded.
                      ' Remove it to allow it to be recreated holding the new count.
                      GroupKeys.Remove (GroupKey)
                  Else
                      ' This record is the first having this group key.
                      ' Thus, the count is 1.
                      Count = 1
                  End If
                  ' (Re)create the group key item with the value of the count of keys.
                  GroupKeys.Add Count, GroupKey
              End If
              ' Add the key and its enumeration.
              ' This will be:
              '   Using no group key: Relative to the full recordset.
              '   Using a group key:  Relative to the group key.
              ' Will fail if the key already has been created.
              Keys.Add Count, CompoundKey
          End If
      
          ' Return the key value as this is the row counter.
          RowNumber = Count
      
      Exit_RowNumber:
          Exit Function
      
      Err_RowNumber:
          Select Case Err
              Case CannotAddKey
                  ' Key is present, thus cannot be added again.
                  Resume Next
              Case CannotRemoveKey
                  ' GroupKey is not present, thus cannot be removed.
                  Resume Next
              Case Else
                  ' Some other error. Ignore.
                  Resume Exit_RowNumber
          End Select
      End Function
      

      那么您的查询可能是:

      SELECT 
          EmployeeID, 
          EventDate, 
          Event, 
          RowNumber(CStr([EventDate]),[EmployeeID] & "-" & CStr(Year([EventDate]))) AS RowCount, 
          Format([RowCount],"00-") & CStr(Year([EventDate])) AS EventCount
      FROM 
          Events
      WHERE 
          RowNumber(CStr([EventDate]),[EmployeeID] & "-" & CStr(Year([EventDate])))<>RowNumber("","",True)
      ORDER BY 
          EventDate;
      

      结果是:

      完整代码可以在 GitHub 上找到:VBA.RowNumbers

      【讨论】:

        猜你喜欢
        • 2020-07-14
        • 2015-10-29
        • 1970-01-01
        • 2023-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-08
        • 2022-11-18
        相关资源
        最近更新 更多