GROUP_CONCAT для MS SQL?

Netmould
Дата: 21.06.2011 18:17:39
Есть таблица с двумя столбцами: телефоны (уникальные записи) и ФИО (могут повторяться).
Для выгрузки в одно капризное ПО надо сделать вьюху, в которой каждому ФИО будет соответствовать все его телефоны (в одном поле через запятую).
select distinct NAME,  

(SELECT STUFF(
 ( SELECT ', ' + PHONE_NUMBER 
	FROM dbo.MOBILE_PHONE_LIST 

	FOR XML PATH ('')),1,1,'')) as Phone
	
	from dbo.MOBILE_PHONE_LIST
Но тут для каждого ФИО выводится одинаковый список из всех имеющихся телефонов, что нехорошо.
Еще был избыточный вариант с проверкой значения по второй таблице:
SELECT
    G.CONTACT_NAME,
    stuff(
    (
    select cast(',' as varchar(max)) + U.PHONE_NUMBER
    from dbo.MOBILE_PHONE_LIST U
    WHERE U.NAME = G.CONTACT_NAME
    order by U.NAME
    for xml path('')
    ), 1, 1, '') AS USERS
FROM
    dbo.USERS G
ORDER BY
    G.CONTACT_NAME ASC;
который просто выводит ошибку "Invalid length parameter passed to the RIGHT function."

Подскажите пожалуйста способ решения!
Baddy
Дата: 21.06.2011 18:32:35
автор
Но тут для каждого ФИО выводится одинаковый список из всех имеющихся телефонов, что нехорошо.


ну так а где же ваш GROUP BY?
Netmould
Дата: 21.06.2011 18:41:38
Подскажите, куда его? Если добавлять к верхнему селекту, то ничего в общем не меняется.
Baddy
Дата: 21.06.2011 18:49:54
Netmould
Дата: 21.06.2011 18:55:12
Жалко, что раньше не посмотрел :).
Влюбом случае, нагуглил еще одно решение (работающее) - мб кому и пригодится.
WITH    q (id, prodname) AS
        (
        SELECT * FROM dbo.MOBILE_PHONE_LIST
        ),
        qs(id, prodname, rn, cnt) AS
        (
        SELECT  id, prodname,
                ROW_NUMBER() OVER (PARTITION BY id ORDER BY prodname),
                COUNT(*) OVER (PARTITION BY id)
        FROM    q
        ),
        t (id, prodname, gc, rn, cnt) AS
        (
        SELECT  id, prodname,
                CAST(prodname AS NVARCHAR(MAX)), rn, cnt
        FROM    qs
        WHERE   rn = 1
        UNION ALL
        SELECT  qs.id, qs.prodname,
                CAST(t.gc + ', ' + qs.prodname AS NVARCHAR(MAX)),
                qs.rn, qs.cnt
        FROM    t
        JOIN    qs
        ON      qs.id = t.id
                AND qs.rn = t.rn + 1
        )
SELECT  id, gc
FROM    t
WHERE   rn = cnt
OPTION (MAXRECURSION 0)
Netmould
Дата: 22.06.2011 18:26:04
Попробовал то что в факе написано (уж очень медленно мой вариант работает), в случае с нетривиальными данными все примеры из фака вываливаются с одинаковой ошибкой - Invalid length parameter passed to the RIGHT function.
step_ks
Дата: 22.06.2011 22:44:07
в факе по обсуждаемой теме вроде нет функции right
Netmould
Дата: 23.06.2011 10:28:17
step_ks,

Я знаю :). У меня тоже нет. Тем не менее, вываливается такая ошибка.
step_ks
Дата: 23.06.2011 10:30:21
запрос-то не хотите показать?
Vaja
Дата: 23.06.2011 10:45:40
автор
SELECT name, (
SELECT a.PHONE_NUMBER +N';' as 'data()'
FROM dbo.MOBILE_PHONE_LIST AS a
WHERE b.name = a.name
for xml path('')
) as PHONE_NUMBERS
from dbo.MOBILE_PHONE_LIST b
group by name