2008-09-19 3 views
9

Tengo dos tablas Organización y Empleado con una relación de uno a muchos, es decir, una organización puede tener múltiples empleados. Ahora quiero seleccionar toda la información de una organización particular más el nombre de todos los empleados de esta organización. ¿Cuál es la mejor manera de hacerlo? ¿Puedo obtener todo esto en un solo conjunto de registros o tendré que obtener varias filas basadas en no? ¿de los empleados? Aquí es una demostración gráfica de algo de lo que quiero:¿Cómo obtener múltiples registros en un registro basado en la relación?

Org_ID  Org_Address Org_OtherDetails Employess 

1   132A B Road List of details  Emp1, Emp2, Emp3..... 

Respuesta

0

Si utiliza Oracle puede crear una función PL/SQL se puede utilizar en su consulta que acepta una organization_id como entrada y devuelve el primer nombre de todos empleados que pertenecen a esa organización como una cadena. Por ejemplo: -

select 
    o.org_id, 
    o.org_address, 
    o.org_otherdetails, 
    org_employees(o.org_id) as org_employees 
from 
    organization o 
0

Todo depende. Si te unes, obtienes toda la información de la organización en cada fila. (1 fila por empleado). Eso tiene un costo. Si hace dos consultas. (Org y Emp) que tiene un costo diferente.

Elija su veneno.

2

en MS SQL que puede hacer:

create function dbo.table2list (@input int) 
returns varchar(8000) 
as 
BEGIN 
declare @putout varchar(8000) 
set @putout = '' 
select @putout = @putout + ', ' + <employeename> 
from <employeetable> 
where <orgid> = @input 
return @putout 
end 

luego hacer:

select * from org, dbo.table2list(orgid) 
from <organisationtable> 

Creo que se puede hacer con COALESCE() también, pero no puede recordar la sintaxis de la parte superior de mi cabeza

+1

Por supuesto, tan pronto como el total de todos los nombres de los empleados, más comas y espacios alcanzan 8000 - ¡tienes un problema! – Valerion

0

La respuesta corta es "no".

Como se menciona en otras respuestas, existen formas específicas de proveedores para lograr este resultado, pero no existe una solución SQL pura que funcione en una sola consulta. ?

lo siento por eso :(

Es de suponer que una de las soluciones específicas del vendedor trabajará para usted

0

Esto es lo que puede hacer, tienes 2 opciones:

select * 
FROM 
    users u 
    LEFT JOIN organizations o ON (u.idorg = o.id); 

De esta manera usted obtendrá datos adicionales en cada fila - información completa de la organización que realmente no necesita.

O puede hacer:

select o.*, group_concat(u.name) 
FROM 
    users u 
    LEFT JOIN organizations o ON (u.idorg = o.id) 
GROUP BY 
    o.id 

http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat

El segundo enfoque es aplicable si usted quiere ver es decir. lista de nombres de usuario "usuario1, usuario2, usuario3", pero no desea operar en los campos ...

3

Dado que la pregunta está etiquetada como MySQL, debería poder utilizar una solución específica de MySQL, , GROUP_CONCAT. Por ejemplo,

select Org_ID, Org_Address, Org_OtherDetails, 
     GROUP_CONCAT(employees) as Employees 
from employees a, organization b 
where a.org_id=b.org_id 
group by b.org_id; 
18

La pregunta original fue base de datos específica, pero tal vez este es un buen lugar para incluir una respuesta más genérica. Es una pregunta común. El concepto que está describiendo a menudo se denomina 'Concatenación de grupo'. No hay una solución estándar en SQL-92 o SQL-99. Por lo tanto, necesitará una solución específica del proveedor.

  • MySQL - Probablemente la solución más sencilla. Use la función integrada GROUP_CONCAT. En el ejemplo que usted quiere algo como esto:
select 
    o.ID, o.Address, o.OtherDetails, 
    GROUP_CONCAT(concat(e.firstname, ' ', e.lastname)) as Employees 
from 
    employees e 
    inner join organization o on o.org_id=e.org_id 
group by o.org_id 
  • PostgreSQL - EDIT: PostgreSQL 9.0 es igual de sencillo ahora que string_agg (expresión, delimitador) está incorporado. Aquí está con 'comas espacio' entre elementos:
select 
    o.ID, o.Address, o.OtherDetails, 
    STRING_AGG((e.firstname || ' ' || e.lastname), ', ') as Employees 
from 
    employees e 
    inner join organization o on o.org_id=e.org_id 
group by o.org_id 

PostgreSQL antes de 9.0 permite definir sus propias funciones de agregado con CREATE agregado. Un poco más de trabajo que MySQL, pero mucho más flexible. Vea esto other post para más detalles. (Por supuesto PostgreSQL 9.0 y más tarde tener esta opción.)

  • & Oracle MS SQL Server - Crear un procedimiento almacenado que toma la ORG_ID como su entrada y salida a los nombres de los empleados concatenados. Luego use este procedimiento almacenado en su consulta. Algunas de las otras respuestas aquí incluyen algunos detalles sobre cómo escribir procedimientos almacenados como estos.
select 
    o.ID, o.Address, o.OtherDetails, 
    MY_CUSTOM_GROUP_CONCAT_PROCEDURE(o.ID) as Employees 
from 
    organization o 
  • Otras tecnologías DBMS - La ruta de procedimiento almacenado es la más probable. Quizás otros puedan actualizar esta respuesta con respuestas más específicas de la tecnología.
0

Para SQL Server Los agregados SQLCLR de este proyecto están inspirados en el ejemplo del código MSDN; sin embargo, funcionan mucho mejor y permiten la clasificación (como cadenas) y delimitadores alternativos si es necesario. Ofrecen casi funcionalidad equivalente a GROUP_CONCAT de MySQL para SQL Server.

una comparación completa de las ventajas/desventajas de los agregados CLR y para la solución de XML se pueden encontrar en la documentación:

http://groupconcat.codeplex.com

Cuestiones relacionadas