Martha le preparado los ejemplos en Access y PostgreSQL, Excel no lo recomiendo para este tipo de consultas, no obstante, excelente la respuesta de Dante (Un saludo).
EN ACCESS
Hago clic sobre el botón Obtiene Segundo del Grupo y obtengo la siguiente consulta
Código del botón
Private Sub btnSegundo_Click()
On Error GoTo hay_error
Dim strSQl As String
' Requiere de la función:
' RT_NumerarParcialSQL()
' Autor JESUS MANSILLA CASTELLS -Mihura-
'Verifico si existe la tabla
If DCount("[Name]", "MSysObjects", "[Name] = 'temgrupos'") = 1 Then
DoCmd.DeleteObject acTable, "temgrupos"
End If
'Verifico si existe la consulta
If DCount("[Name]", "MSysObjects", "[Name] = 'qryGrupos'") = 1 Then
DoCmd.DeleteObject acQuery, "qryGrupos"
End If
strSQl = "SELECT tblempleados.idempleado" & vbCrLf
strSQl = strSQl & " , tblempleados.idseccion" & vbCrLf
strSQl = strSQl & " , tblempleados.empleado" & vbCrLf
strSQl = strSQl & " , tblempleados.sueldo" & vbCrLf
strSQl = strSQl & " , RT_NumerarParcialSQL([idseccion]) AS cons INTO temgrupos" & vbCrLf
strSQl = strSQl & " FROM tblempleados" & vbCrLf
strSQl = strSQl & " ORDER BY tblempleados.idseccion" & vbCrLf
strSQl = strSQl & " , tblempleados.sueldo DESC;"
CurrentDb.Execute strSQl
strSQl = "SELECT temgrupos.idempleado" & vbCrLf
strSQl = strSQl & " , temgrupos.idseccion" & vbCrLf
strSQl = strSQl & " , temgrupos.empleado" & vbCrLf
strSQl = strSQl & " , temgrupos.sueldo" & vbCrLf
strSQl = strSQl & " FROM temgrupos" & vbCrLf
strSQl = strSQl & " WHERE temgrupos.cons=2" & ";"
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Set db = CurrentDb()
Set qdf = db.CreateQueryDef("qryGrupos", strSQl)
' Abre la consulta y muéstrala
DoCmd.OpenQuery qdf.Name, acViewNormal
' Libera la memoria
Set qdf = Nothing
Set db = Nothing
hay_error_Exit:
Exit Sub
hay_error:
MsgBox "Ocurrió el error " & Err.Number & vbCrLf & Err.Description, vbCritical, "Error"
Resume hay_error_Exit
End Sub
Función RT_NumerarParcialSQL()
Public Function RT_NumerarParcialSQL(nDato) As Long
'variable que no se pierde entre las distintas llamadas
Static nCONTADOR As Long, nANTERIOR As String
If IsNull(nDato) Then 'si nDato es nulo: Iniciamos valor
nCONTADOR = 0
nANTERIOR = ""
Exit Function
End If
'- si nDato es igual al valor memorizado sumamos 1 al contador
If nDato = nANTERIOR Then
nCONTADOR = nCONTADOR + 1
Else '- iniciamos valor y memorizamos el anterior
nCONTADOR = 1
nANTERIOR = nDato
End If
RT_NumerarParcialSQL = nCONTADOR
End Function
Public Function RT_NumerarParcialSQL(nDato) As Long
'variable que no se pierde entre las distintas llamadas
Static nCONTADOR As Long, nANTERIOR As String
If IsNull(nDato) Then 'si nDato es nulo: Iniciamos valor
nCONTADOR = 0
nANTERIOR = ""
Exit Function
End If
'- si nDato es igual al valor memorizado sumamos 1 al contador
If nDato = nANTERIOR Then
nCONTADOR = nCONTADOR + 1
Else '- iniciamos valor y memorizamos el anterior
nCONTADOR = 1
nANTERIOR = nDato
End If
RT_NumerarParcialSQL = nCONTADOR
End Function
Puede cambiar el 2 por otro número, en este caso sería mejor elaborar una función con este código y pasar el número como parámetro.
EN POSTGRESQL (Mi preferido)
SELECT idempleado,empleado,idseccion ,sueldo
FROM (
SELECT idempleado,empleado,idseccion, sueldo,
DENSE_RANK() OVER (PARTITION BY idseccion ORDER BY sueldo DESC) as rnk
FROM tblempleados
) As t
WHERE t.rnk = 2
ORDER BY t.idseccion;
Observe la potencia y la simplicidad del script en comparación con Access y por su puesto con Excel.
Resultado de la consulta en PostgreSQL
Si le tiene alguna duda la puede hacer a mi correo [email protected]