2010-09-03 2 views
3

Я пытаюсь использовать «для Xml Path» T-SQL для создания списка значений, разделенных запятыми, из столбца. Это, кажется, отлично работает, но проблема в том, что я хотел бы получить количество элементов в списке, разделенном запятыми. Вот пример кода, который я использую для создания разделенного запятыми список:Sql Для Xml Path get node count

Create Table #List ([col] varchar) 

Insert Into #List Select '1'; 
Insert Into #List Select '2'; 
Insert Into #List Select '3' 

Select ',' + [col] From #List For Xml Path('') 

Это дает 1,2,3 результатов, как и ожидалось, но нет никакого способа, чтобы получить количество, что есть 3 вещей , Любая попытка добавить счет просто добавит его в xml. Я объединил этот код с КТР, чтобы получить количество:

With CTE As (
    Select 
     [col] 
    From 
     #List 
) 
Select 
    (Select ',' + [col] From #List For Xml Path('')) As [List], 
    Count(*) As [Count] 
From 
    CTE 

есть более простой/уборщик способ получить количество узлов без использования КТРА? Было указано, что вы можете просто дублировать предложение from внутри внутреннего выбора и снаружи, но это требует сохранения синхронных предложений. Я хочу получить и список и счет, но только одно из предложения, написанное один раз.

ответ

2

Как насчет рисования данных из КТРА вместо временной таблицы?

With CTE As (
    Select 
     [col] 
    From 
     #List 
    -- Many joins 
    -- Complicated where clause 
) 
Select 
    (Select ',' + [col] From Cte For Xml Path('')) As [List], 
    Count(*) As [Count] 
From 
    CTE 

Это позволит вам сохранить свои соединения и искать предикаты в одном месте.

+0

Это на самом деле то, что я использовал. Тем не менее, мне пришлось поставить сложный выбор в таблицу temp перед использованием CTE. Когда я впервые присоединился к CTE, производительность была ужасной. Потребовалось около 2 секунд, чтобы запрос внутри CTE возвращался, однако весь запрос должен выполняться с часами свертывания списка запятой. Это заняло так много времени, что я никогда не позволял этому закончить весь путь. Если сначала поставить сложный выбор в временную таблицу, запрос займет секунду. Единственное, что я могу понять, это то, что выбор внутри CTE повторялся для каждой итерации ??? – user355930

1

Вам не нужно КТР вы можете использовать подзапрос подход непосредственно

SELECT 
     COUNT(*) AS [Count], 
     (SELECT ',' + [col] FROM #List FOR XML PATH('')) AS [List] 
FROM #List 
+0

Это приемлемое решение, но проблема в том, что он требует дублирования из логики дважды. Если бы я вытащил из заявления, в котором было 10 объединений, мне пришлось бы повторять соединения внутри подзапроса и в предложении from. Я хочу, чтобы иметь логику соединения, написанную один раз, и получить список запятой и счетчик. Я изменю свой вопрос. Я пытался проголосовать за тебя, но у меня нет достаточного количества репутации. – user355930