Calculo de mediana en una consulta de Access

En una tabla de Access tengo diversos objetos (p. E. Lápiz-1, lápiz-2, lápiz-3, goma-1, etc.) y a cada objeto le corresponde un peso (cada lápiz o goma pesan diferente, etc.). Necesito crear una consulta para una vez agrupadas por tipo de objeto (lápiz, goma, etc.) me calcule la media y la mediana de cada tipo. Para calcular la media no hay problema pues agrupo por tipo de objeto y luego en totales marco promedio, pero para la mediana no veo manera. ¿Se os ocurre alguna opción para calcular la mediana (o el percentil 50 que es lo mismo) con ACCESS?

1 Respuesta

Respuesta
1

Tendrías que definirte una función que ordene los objetos y después seleccione el que está en el centro.

Cuando son impartes no hay problema pues es el objeto que está en la posición "entero(nº de objetos/2)+1", pero cuando son pares la mediana... ¿cuál sería?

Otra cosa: ¿Cuál es la estructura de la tabla y cuales los campos para ordenar los objetos?

La función será de un estilo a esta:

Option Explicit
Function mediana(ByVal txtObjetoComo As String) As String
Dim rs As DAO.Recordset
Dim txtSql As String
Dim n As Integer
txtSql = "SELECT * " & _
"FROM <nombre de la tabla> " & _
"WHERE objeto like '*" & Trim$(txtObjetoComo) & "*' " & _
"order by <nombre campo objeto>,<nombre campo peso objeto>"
Set rs = CurrentDb().OpenRecordset(txtSql, dbOpenDynaset)
If Not rs.EOF Then rs.MoveLast
If rs.RecordCount = 0 Then
' No hay ningún objeto que cumpla la condición. Devolvemos ""
mediana = ""
Else
If rs.RecordCount Mod 2 = 1 Then
' Al ser impares tomamos el objeto central
n = Int(rs.RecordCount / 2) + 1
Else
' Al ser pares... tomaremos el anterior, por poner uno
n = Int(rs.RecordCount / 2)
End If
rs.MoveFirst
If n > 1 Then rs.Move n - 1
' Devolvemos el nombre del objeto
mediana = rs!<nombre campo objeto>
End If
rs.Close
End Function

Gracias por la contestación. La mediana si son pares debería ser la media de los dos valores centrales, pero ni idea de cómo hacerlo en ACCESS.

Sobre la estructura de la tabla: está formada por un campo "" que es autonumérico, otro "Tipo de objeto" donde va si es lápiz, goma, etc. Y otro "Peso", donde vienen los gramos de cada objeto (cada lápiz tiene un peso, etc.). Para calcular la media y la desviación típica de cada uno de los tipos de objeto he generado una consulta de totales donde agrupo por "tipo de objeto" y pongo dos campos "Peso" donde en uno me calcula el promedio y en otro la desviación típica (una vez agrupado por tipo, claro). En total tengo unos 5.000 registros con unos 100 tipos de objeto diferentes y prefiero mantenerme en ACCESS para que se actualice cada vez que inserto datos nuevos.

Por lo que cuentas ya veo que es mucho más difícil que calcular la media o la desviación típica, por más que en otros programas como Excel es igual de sencillo. Hasta la fecha nunca he "metido" código, me he manejado con consultas de totales, etc., pero imagino que tendré que intentarlo.

Muchas gracias

Prueba con esta función:

Option Explicit
Function mediana(ByVal txtObjetoComo As String) As Variant
Dim rs As DAO.Recordset
Dim txtSql As String
Dim n As Integer
Dim aux As Double
txtSql = "SELECT * " & _
"FROM <nombre de la tabla> " & _
"WHERE [tipo de objeto] like '" & Trim$(txtObjetoComo) & "' " & _
"order by peso"
Set rs = CurrentDb().OpenRecordset(txtSql, dbOpenDynaset)
If Not rs.EOF Then rs.MoveLast: rs.MoveFirst
If rs.RecordCount = 0 Then
' No hay ningún objeto que cumpla la condición. Devolvemos ""
mediana = Null
Else
If rs.RecordCount Mod 2 = 1 Then
' Al ser impares tomamos el objeto central
n = Int(rs.RecordCount / 2) + 1
If n > 1 Then rs.Move n - 1
mediana = rs!peso
Else
' Al ser pares... tomamos la media de los 2 centrales
n = Int(rs.RecordCount / 2)
If n > 1 Then rs.Move n - 1
aux = rs!peso
rs.MoveNext
mediana = (aux + rs!peso) / 2
End If
End If
rs.Close
End Function

Tienes que poner el nombre correcto de la tabla y comprueba que los campos los haya puesto bien.

En la consulta puedes poner:

mediana([tipo de objeto]) para que te de ese objeto sólo

Mediana("*") para la mediana total

Muchísimas gracias por la ayuda, pero creo que necesito un poco más de información ya que es la primera vez que escribo código. Tras largo tiempo he deducido que tenía que escribir la función que me has dicho en una cosa que llaman módulo (¿con eso ya queda incorporada?) poniendo el nombre correcto de la tabla, etc. pero luego en la consulta no sé cómo hacer para que me calcule la mediana del campo peso. He intentado en la consulta abrir la tabla donde están esos campos, poner el campo "Tipo de objeto" y en totales "agrupado por", y otro campo mediana(["peso"]), pero no sale nada de nada. El mensaje que aparece es "La función mediana no está definida en la expresión". Como ves necesito saber exactamente cómo hacer la consulta..., pero gracias de todos modos.

Efectivamente el código va dentro de los módulos y/o formularios e informes. En tu caso sería en un módulo.

Para calcular la mediana en una consulta, en uno de los campos puedes poner:

Mediana del objeto: mediana([tipo de objeto])

Con ello te calculará la mediana para ese objeto.

Si quieres la mediana del total de los objetos pondrías:

Mediana total: mediana("*")

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas