我有两个表,组织和员工有一对多的关系,即一个组织可以有多个员工。现在,我想选择特定组织的所有信息以及该组织的所有员工的名字。最好的方法是什么?我可以在单个记录集中获得所有这些,或者我必须基于否获得多行。员工?以下是我想要的图形演示:
Org_ID Org_Address Org_OtherDetails Employess
1 132A B Road List of details Emp1, Emp2, Emp3.....
答案 0 :(得分:18)
最初的问题是数据库特定的,但也许这是一个包含更通用答案的好地方。这是一个常见的问题。您描述的概念通常称为“组级联”。 SQL-92或SQL-99中没有标准解决方案。因此,您需要特定于供应商的解决方案。
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
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
9.0之前的PostgreSQL允许您使用CREATE AGGREGATE定义自己的聚合函数。比MySQL更多的工作,但更灵活。有关详细信息,请参阅此other post。 (当然PostgreSQL 9.0及更高版本也有此选项。)
select o.ID, o.Address, o.OtherDetails, MY_CUSTOM_GROUP_CONCAT_PROCEDURE( o.ID ) as Employees from organization o
答案 1 :(得分:3)
由于问题被标记为MySQL,您应该能够使用特定于MySQL的解决方案,即GROUP_CONCAT。例如,
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;
答案 2 :(得分:2)
在MS SQL中你可以这样做:
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
然后做:
select * from org, dbo.table2list(orgid)
from <organisationtable>
我认为你也可以用COALESCE()来做,但不记得我头脑中的语法
答案 3 :(得分:0)
如果您使用Oracle,您可以创建一个PL / SQL函数,您可以在查询中使用该函数接受organization_id作为输入,并将属于该组织的所有员工的名字作为字符串返回。例如: -
select
o.org_id,
o.org_address,
o.org_otherdetails,
org_employees( o.org_id ) as org_employees
from
organization o
答案 4 :(得分:0)
一切都取决于。 如果您进行连接,则会获得每一行的所有组织数据。 (每位员工1排)。这有成本。 如果你做两个查询。 (Org和Emp)有不同的成本。
选择你的毒药。
答案 5 :(得分:0)
简短的回答是“不”。
正如其他答案所述,有特定于供应商的方法可以实现此结果,但是没有纯SQL解决方案可以在一个查询中使用。
抱歉:(据推测,某个供应商特定的解决方案适合您?
答案 6 :(得分:0)
这是你可以做的,你有两个选择:
select *
FROM
users u
LEFT JOIN organizations o ON (u.idorg = o.id);
通过这种方式,您可以获得每行的额外数据 - 您并不真正需要的完整组织信息。
或者你可以这样做:
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
如果你想看到ie,第二种方法是适用的。用户名列表“user1,user2,user3”,但不想对字段本身进行操作...
答案 7 :(得分:0)
对于SQL Server SQLCLR此项目中的聚合受MSDN代码示例的启发,但它们执行得更好,并允许排序(如字符串)和备用分隔符(如果需要)。它们为MySQL的SQL Server GROUP_CONCAT提供几乎等效功能。
可以在文档中找到CLR聚合和FOR XML解决方案的优缺点的完整比较:
答案 8 :(得分:0)
对于 SQL Server 2017 和 Azure SQL,现在有一个函数 STRING_AGG (Transact-SQL) 使其与 MySQL 相提并论:
https://docs.microsoft.com/en-us/sql/t-sql/functions/string-agg-transact-sql?view=sql-server-ver15。
SELECT attribute1, STRING_AGG (attribute2, '|') AS Attribute2
FROM table
GROUP BY attribute