Как объединить идентификаторы uniqueidentifier в запросе T-SQL CTE в строку

#sql-server #tsql #sql-cte

#sql-сервер #tsql #sql-cte

Вопрос:

Я хочу создавать uniqueidentifier идентификаторы, разделенные запятой, в виде строки в запросе T-SQL CTE:

 WITH departmentcte(ID, Name, ParentID, LEVEL, FullPath) AS
( 
    SELECT 
        ID, Name, ParentID, 0 AS LEVEL, 
        CAST(Name AS VARCHAR(1024)) AS FullPath 
    FROM 
        ItemModels 
    WHERE 
        ParentID IS NULL

    UNION ALL  

    SELECT 
        d.ID, d.Name, d.ParentID, departmentcte.LEVEL   1 AS LEVEL,
        CAST(departmentcte.FullPath   ''   CAST(d.Name AS VARCHAR(1024)) AS VARCHAR(1024)) AS FullPath  
    FROM 
        ItemModels d
    INNER JOIN 
        departmentcte ON departmentcte.ID = d.ParentID
)
SELECT ID, Name, FullPath  
FROM departmentcte;
  

Он возвращает этот результат, как и ожидалось:

введите описание изображения здесь

Но я хотел бы получить все идентификаторы подмножества, например

введите описание изображения здесь

Итак, я пытаюсь выполнить следующий запрос и получаю ошибку

Введите несоответствие между частями bind и recursive в столбце «SubIDs» рекурсивного запроса «departmentcte».

 WITH departmentcte(ID, Name, ParentID, LEVEL, FullPath, SubIDs) AS
( SELECT ID, Name, ParentID, 0 AS LEVEL, CAST(Name AS VARCHAR(1024)) AS FullPath, 
    convert(nvarchar(36), ID) as SubIDs FROM ItemModels WHERE ParentID IS NULL
 UNION ALL  
 SELECT d.ID, d.Name, d.ParentID, departmentcte.LEVEL   1 AS LEVEL,
      CAST(departmentcte.FullPath   ''   CAST(d.Name AS VARCHAR(1024)) AS VARCHAR(1024)) AS FullPath,    
      ( ISNULL(departmentcte.SubIDs,'')   ''   convert(nvarchar(36), d.ID) )  AS SubIDs 
 FROM ItemModels d
      INNER JOIN departmentcte ON departmentcte.ID = d.ParentID)
SELECT ID, FullPath, SubIDs  FROM departmentcte;
  

Как я вижу, SubIDs имеет тип данных nvarchar, так в чем проблема?

Ответ №1:

Спасибо всем, я нашел решение

     WITH departmentcte(ID,ParentID, LEVEL, FullPath, SubIDs) AS
    ( SELECT ID,  ParentID, 0 AS LEVEL, CAST(Name AS VARCHAR(1024)) AS FullPath, convert(varchar(2048), ID) as SubIDs 
        FROM ItemModels WHERE ParentID IS NULL
     UNION ALL  
     SELECT d.ID,  d.ParentID, departmentcte.LEVEL   1 AS LEVEL, 
          CAST(        departmentcte.FullPath    ','    CAST(d.Name AS VARCHAR(1024)) AS VARCHAR(1024)) AS FullPath,      
          CAST( ISNULL(departmentcte.SubIDs,'')   ','   convert(nvarchar(36), d.ID)  AS VARCHAR(2048))  AS SubIDs 
     FROM ItemModels d INNER JOIN departmentcte ON departmentcte.ID = d.ParentID)

SELECT *  FROM departmentcte;
  

Идея состоит в том, чтобы использовать одинаковый размер varchar/nvarchar в обоих полях UNION ALL .
В моем случае это varchar(2048)

Комментарии:

1. Я как раз собирался опубликовать ответ, очень похожий на этот. Кстати, в следующий раз, когда вы будете спрашивать, пожалуйста, укажите либо демонстрационную ссылку, либо некоторые образцы данных. Большинство людей не смогут сильно помочь с вопросом, который вы задали выше.