| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Составление SQL-запросов > слияние строк в sql-запросе |
| Автор: swetik1981 16.9.2009, 22:55 |
| Имею базу данных, которая упрощённо выглядит так: База данных - Предприятие: Отдел Сотрудник 1 Степанов 1 Фёдоров 1 Иванов 2 Пивоваров 3 Сидоров 3 Коновалов Мне необходимо вывести на экран таблицу, состоящую из трёх столбцов с указанием номера отдела, количества работающих в нём сотрудников и списка сотрудников. Причём список всех сотрудников, работающих в отделе должен быть представлен в одной ячейке данных С количеством сотрудников всё понятно: "SELECT Отдел, COUNT(Отдел) FROM Предприятие GROUP BY Отдел" Но как загнать в одну ячейку всех сотрудников, работающих в соответствующем разделе, что вывод данных был таков: Отдел Количество Сотрудники 1 3 Степанов Фёдоров Иванов 2 1 Пивоваров 3 2 Сидоров Коновалов Есть ли какая-то функция собирающая в одну строку все строки, представленные в соответствующем наборе записей? |
| Автор: Deniz 17.9.2009, 05:49 |
| СУБД? Вроде стандартным методами не получится. (имеется ввиду 1 sql-запросом по стандартам SQL) А вдруг в отделе будет работать >100 чел? Строчка получится очень длинной. Может пересмотреть подход и сделать другую реализацию? |
| Автор: Akina 17.9.2009, 07:53 |
| В некоторых СУБД такая функция есть (скажем group_concat в MySQL), в других это надо организовывать пользовательской функцией. |
| Автор: skyboy 17.9.2009, 08:59 |
| ...а в некоторых сделать это средствами только SQL может вовсе оказаться невозможно... в таком случае можно делать группировку на клиенте. |
| Автор: Zloxa 17.9.2009, 09:21 |
| Ну, коли уж тут почти все старожилы отметились и я свои пять копеек внесу.... Вообще такая функция очень не лаконично вписывается в концепцию аггрегации SQL. Все агрегатные функции ANSI SQL детерминированы - на одном и том же наборе данных дают одинаковый результат в не зависимости от порядка перебора набора данных при группировке. В случае же с аггрегирующей конкатенацией мы детерминированный результат получить можем лишь дополнительно указав критерии сортировки. А такая фича находится за пределами стандарта и вне концепции аггрегирования предусмотренной нынешним стандартом. Другими словами аггрегирующая конкатенация - очень не кошерна. |
| Автор: Gluttton 17.9.2009, 09:56 | ||||
| И тут такой я на белом коне Итак для таблицы: ![]() Вот такой вот запрос (Firebird 2.1):
Вернет вот таки данные: ![]() Что происхоит в этом запросе... Для краткости я приведу результат внутреннего подзапроса:
![]() А всё остальное (т.е. внешний запрос) необходимо для того, что бы получить требуемые данные. Кстати это мой дебют в рекурсивных запросах |
| Автор: Gudinya 17.9.2009, 10:22 | ||||
Ну раз на коне тут уже влетали, въеду ка я на сером ослике... при том что 99% кода подсмотрел в Oracle Magazine
|
| Автор: Gluttton 17.9.2009, 11:45 | ||
Спасибо! Оверхедно - да, недетерминировано - не сказал бы. Запрос не будет работать (будет не коректно работать) на однофамильцах... Идея в том, что бы тех, кого "уже сосчитали" не рассматривали повторно... Про однофамильцев, думаю, что при такой структуре таблицы, коректно обработать однофамильцев из одного отдела будет крайне сложно (для этого прийдеться "играться" с подсчетом количества однофамильцев в отделе и потом их столько раз и повторять)... А вот если был бы ключик, тогда можно было бы устранить этот недостаток... swetik1981, что с однофамильцами делать будем? А вот за это спасибо! [вот что получилось после всех внесенных изменений:
Gudinya, не разобрался я в приведенном запросе... Видать пора начинать изучать Oracle |
| Автор: Zloxa 17.9.2009, 12:40 |
под недетерменированностью я подразумевал что порядок следования фамилий в результате будет зависеть от внешних факторов (порядок заполнения записями таблицы, план запроса....)... Т.е. в разные моменты времени (или разных средах), но на одинаковых данных запрос может возвращать разные результаты Я эту "некорректность" наоборот воспринял как фишку.... |