У меня есть две таблицы, Организация и Сотрудник, имеющие отношение один ко многим, то есть в одной организации может быть несколько сотрудников. Теперь я хочу выбрать всю информацию о конкретной организации, а также имена всех сотрудников этой организации. Как лучше всего это сделать? Могу ли я получить все это в одном наборе записей, или мне придется получить несколько строк в зависимости от номера. сотрудников? Вот небольшая графическая демонстрация того, что я хочу:
Org_ID Org_Address Org_OtherDetails Employess
1 132A B Road List of details Emp1, Emp2, Emp3.....






Если вы используете 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
Все это зависит. Если вы выполните соединение, вы получите все данные организации в каждой строке. (По 1 строке на сотрудника). Это имеет свою цену. Если вы сделаете два запроса. (Org и Emp), у которых другая стоимость.
Выбрать свой яд.
в 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 (), но не могу вспомнить синтаксис из головы
Короткий ответ - нет".
Как отмечалось в других ответах, существуют способы достижения этого результата, зависящие от поставщика, но нет чистого решения SQL, которое работает с одним запросом.
Извини за это :(
Предположительно, вам подойдет одно из решений конкретного производителя?
Вот что вы можете сделать, у вас есть 2 варианта:
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
Второй подход применим, если вы хотите увидеть, т.е. список имен пользователей "user1, user2, user3", но не хотят работать с самими полями ...
Поскольку вопрос помечен как 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;
Первоначальный вопрос касался конкретной базы данных, но, возможно, это хорошее место для включения более общего ответа. Обычный вопрос. Концепция, которую вы описываете, часто называют «групповой конкатенацией». В 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
PostgreSQL до 9.0 позволяет вам определять свои собственные агрегатные функции с помощью CREATE AGGREGATE. Немного больше работы, чем MySQL, но гораздо более гибкий. См. Этот другой пост для более подробной информации. (Конечно, PostgreSQL 9.0 и более поздние версии также имеют эту опцию.)
select o.ID, o.Address, o.OtherDetails, MY_CUSTOM_GROUP_CONCAT_PROCEDURE( o.ID ) as Employees from organization o
Для SQL Server агрегаты SQLCLR в этом проекте вдохновлены примером кода MSDN, однако они работают намного лучше и позволяют при необходимости сортировать (в виде строк) и использовать альтернативные разделители. Они предлагают функциональность, эквивалентную почти MySQL GROUP_CONCAT для SQL Server.
Полное сравнение преимуществ / недостатков агрегатов CLR и решения FOR XML можно найти в документации:
Для 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
Конечно, как только общее количество имен всех ваших сотрудников, включая запятые и пробелы, достигнет 8000 - у вас проблема!