ID's de otra tabla en columna - Access o SQL Server

Tengo dos tablas, una de trabajadores y en la misma, tengo una columna con la categoría. El tema es que dado que un trabajador puede tener más de una categoría, guardo la id_categoría separado por ;. El tema es que ahora quiero sacar un listado y sustituir las id's por el nombre de la categoría y no me sale. He probado con access y con SQL Server STRING_SPLIT y, con este último, ¿obtengo el resultado pero me saca por cada id una row. Sabéis cómo podría solventarlo? Gracias de antemano.

TABLA TRABAJADORES
ID_TRABAJADOR - NOMBRE - CATEGORIA
1 - Paco - 1;2;

2 - Antonio - 3;


TABLA CATEGORIAS
ID_CATEGORIA - NOMBRE
1 - Programador

2 - Diseñador gráfico

3 - Administrativo


TABLA QUE QUIERO
ID_TRABAJADOR - NOMBRE - CATEGORIA
1 - Paco - Programador y Diseñador gráfico

2 - Antonio - Administrativo

3 respuestas

Respuesta
1

Le dejo otra opción con una función para Access y los scripts para SQL Server y PostgreSQL

PARA ACCESS

TABLAS

DISEÑO DE LA CONSULTA

RESULTADO DE LA CONSULTA

CÓDIGO DE LA FUNCIÓN

Function ObtenerNombresCategorias(idCategorias As String) As String
    Dim categorias() As String
    Dim nombreCategoria As String
    Dim i As Integer
    categorias = Split(idCategorias, ";")
    For i = LBound(categorias) To UBound(categorias)
        ' Aquí debes reemplazar "TablaCategorias" con el nombre de tu tabla de categorías
        nombreCategoria = DLookup("NombreCategoria", "TablaCategorias", "idCategoria = " & categorias(i))
        ' Concatenar los nombres de categoría separados por ","
        ObtenerNombresCategorias = ObtenerNombresCategorias & nombreCategoria & ", "
    Next i
    ' Eliminar la última coma y espacio
    If Len(ObtenerNombresCategorias) > 0 Then
        ObtenerNombresCategorias = Left(ObtenerNombresCategorias, Len(ObtenerNombresCategorias) - 2)
    End If
End Function

PARA SQL SERVER

SELECT t.ID, t.Nombre, STRING_AGG(c.NombreCategoria, ', ') AS NombresCategorias
FROM Trabajadores t
CROSS APPLY STRING_SPLIT(t.IDCategorias, ';') s
JOIN TablaCategorias c ON s.value = c.idCategoria
GROUP BY t.ID, t.Nombre

PARA POSTGRESQL (Mi preferido)

SELECT t.ID, t.Nombre, array_to_string(array_agg(c.NombreCategoria), ', ') AS NombresCategorias
FROM Trabajadores t
JOIN unnest(string_to_array(t.IDCategorias, ';')) s ON s = c.idCategoria
JOIN TablaCategorias c ON s = c.idCategoria
GROUP BY t.ID, t.Nombre

Reemplace la función de Access por la siguiente, toda vez, que la anterior da error cuando hay 1 sola categoría.

Function ObtenerNombresCategorias(idCategorias As String) As String
    Dim categorias() As String
    Dim nombreCategoria As String
    Dim i As Integer
    categorias = Split(idCategorias, ";")
    If UBound(categorias) > 0 Then
        For i = LBound(categorias) To UBound(categorias)
            ' Aquí debes reemplazar "TablaCategorias" con el nombre de tu tabla de categorías
            nombreCategoria = DLookup("NombreCategoria", "TablaCategorias", "idCategoria = " & categorias(i))
            ' Concatenar los nombres de categoría separados por ","
            ObtenerNombresCategorias = ObtenerNombresCategorias & nombreCategoria & ", "
        Next i
        ' Eliminar la última coma y espacio
        If Len(ObtenerNombresCategorias) > 0 Then
            ObtenerNombresCategorias = Left(ObtenerNombresCategorias, Len(ObtenerNombresCategorias) - 2)
        End If
    ElseIf UBound(categorias) = 0 Then
        ' Solo hay una categoría
        ' Aquí debes reemplazar "TablaCategorias" con el nombre de tu tabla de categorías
        ObtenerNombresCategorias = DLookup("NombreCategoria", "TablaCategorias", "idCategoria = " & categorias(0))
    End If
End Function
Respuesta
1

Por si te puede dar una idea. Tengo una tabla Categorias como

Y una tabla Trabajadores, a la que le he añadido un campo EnLetra porque no sé como quieres mostrar las categorías que le corresponden

En el formulario Trabajadores le he puesto un botón porque he supuesto que ya tienes datos en la tabla, pero en el código puedes ponerle que vaya actualizando la tabla al abrir el formulario

Puedes ver que esta "seleccionado" el registro1. Si pulso el botón

En el siguiente

En este caso, el código del botón es( pero ya te digo que personalmente le diría que actualizara la tabla Trabajadores)

Private Sub Comando7_Click()
Dim contador As Byte, primero, segundo
contador = Nz(Len([IdCategoria]) - Len(Replace([IdCategoria], ";", "")), 0)
Select Case contador
Case Is = 0
EnLetra = DLookup("categoria", "categorias", "idcategoria=val([idcategoria])")
Case Is = 1
primero = Left([IdCategoria], InStr([IdCategoria], ";") - 1)
segundo = Mid([IdCategoria], InStrRev([IdCategoria], ";") + 1)
EnLetra = DLookup("categoria", "categorias", "idcategoria=val(" & primero & ")") & ";" & DLookup("categoria", "categorias", "idcategoria=val(" & segundo & ")")
End Select
End Sub

Primero comprueba si hay uno o más idcategoria y en función de eso, "divide" la cadena. Le digo lo de val porque idcategoria es texto

Pero ya te digo que se puede hacer de más formas.

Respuesta
1

Se puede hacer de varias formas, todo depende de la cantidad de datos.

Una sencilla es la función Choose, un ejemplo:

¿
? Choose(1,"Programador","Diseñador gráfico", "Administrativo")
Programador

Y si se utiliza una función esta puede entrar en bucle y hacer tantos cambios como elementos (1 ... N) con un For/Next

Un clásico muy similar como posible ejemplo es la traducción de una cifra a letra en la que el limite es la creatividad disponible.

Los cambios antes mencionados se harían con la función Reemplace (se quedo en el tintero)

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas