2016-10-14 7 views
1

У меня есть следующий SQL результата от SELECT запроса:SQL SELECT: сцепляется столбец с разрывами строк и заголовком в группу

ID | category| value | desc 
1 | A  | 10 | text1 
2 | A  | 11 | text11 
3 | B  | 20 | text20 
4 | B  | 21 | text21 
5 | C  | 30 | text30 

Этого результат сохраняется во временной таблице с именем #temptab. Эта временная таблица затем используется в другом SELECT для создания нового столбца посредством конкатенации строк (не спрашивайте меня о подробном обосновании этого. Это код, который я взял у коллеги). Через FOR XML PATH() вывод этого столбца представляет собой список результатов и затем используется для отправки писем клиентам.

Второй SELECT выглядит следующим образом:

SELECT t1.column, 
     t2.column, 
     (SELECT t.category + ' | ' + t.value + ' | ' + t.desc + CHAR(9) + CHAR(13) + CHAR(10) 
      FROM #temptab t 
      WHERE t.ID = ttab.ID 
      FOR XML PATH(''),TYPE).value('.','NVARCHAR(MAX)') AS colname 
FROM table1 t1 
... 
INNER JOIN #temptab ttab on ttab.ID = someOtherTable.ID 
... 

Не желая вдаваться в излишние подробности, столбец colname заселяется с несколькими записями (из-за нескольких матчей) и, следовательно, более длинная строка хранится в эта колонка (CHAR(9) + CHAR(13) + CHAR(10) - это, по существу, разрыв строки). Результат/содержание colname выглядит следующим образом (используются для отправки почты клиентов):

A | 10 | text1 
A | 11 | text11 
B | 20 | text20 
B | 21 | text21 
C | 30 | text30 

Теперь я хотел бы знать, если есть способ более красиво форматировать эту выходную строку. В лучшем случае был бы сгруппировать ту же категорию вместе и добавить заголовок и пустую строку между различными категориями:

*A* 
A | 10 | text1 
A | 11 | text11 

*B* 
B | 20 | text20 
B | 21 | text21 

*C* 
C | 30 | text30 

Моим вопросом: Как я должен изменить приведенный выше запрос (особенно строка-конкатенация-часть) для достижения вышеуказанного форматирования? Я думал об использовании инструкции GROUP BY, но это, очевидно, не дает желаемого результата.

Edit: Я использую Microsoft SQL Server 2008 R2 (SP2) - 10.50.4270.0 (X64)

+0

Какие dbms вы используете? (Некоторый специфический SQL-код продукта.) – jarlh

+1

@jarlh Я считаю, что for-xml-путь является специфичным для SQL-сервера, мы просто не знаем версию. хотя я бы подумал, что можно с уверенностью сказать, что это 2008 + – xQbert

+0

Microsoft SQL Server 2008 R2 (SP2) - 10.50.4270.0 (X64) (* обновлено в сообщении *) – beta

ответ

1
Declare @YourTable table (ID int,category varchar(50),value int, [desc] varchar(50)) 
Insert Into @YourTable values 
(1,'A',10,'text1'), 
(2,'A',11,'text11'), 
(3,'B',20,'text20'), 
(4,'B',21,'text21'), 
(5,'C',30,'text30') 

Declare @String varchar(max) = '' 

Select @String = @String + Case when RowNr=1 Then Replicate(char(13)+char(10),2) +'*'+Category+'*' Else '' end 
         + char(13)+char(10) + category + ' | ' + cast(value as varchar(25)) + ' | ' + [desc] 
From (
     Select * 
       ,RowNr=Row_Number() over (Partition By Category Order By Value) 
     From @YourTable 

    ) A Order By Category, Value 

Select Substring(@String,5,Len(@String)) 

Возвращает

*A* 
A | 10 | text1 
A | 11 | text11 

*B* 
B | 20 | text20 
B | 21 | text21 

*C* 
C | 30 | text30 
+0

Мне нужно решение, которое является адаптацией/расширением запроса SELECT, которое я покажу в своем сообщении. Я думаю, что ваше решение не работает для этого. – beta

+1

@beta Понял, я сделаю еще один выстрел в него. –

+0

Я заимствовал ваш стол. Надеюсь, вы не против. +1 с моей стороны – Shnugo

0

Это должно вернуть то, что вы хотите

Declare @YourTable table (ID int,category varchar(50),value int, [desc] varchar(50)) 
Insert Into @YourTable values 
(1,'A',10,'text1'), 
(2,'A',11,'text11'), 
(3,'B',20,'text20'), 
(4,'B',21,'text21'), 
(5,'C',30,'text30'); 

WITH Categories AS 
(
    SELECT category 
      ,'**' + category + '**' AS CatCaption 
      ,ROW_NUMBER() OVER(ORDER BY category) AS CatRank 
    FROM @YourTable 
    GROUP BY category 
) 
,Grouped AS 
(
    SELECT c.CatRank 
      ,0 AS ValRank 
      ,c.CatCaption AS category 
      ,-1 AS ID 
      ,'' AS Value 
      ,'' AS [desc] 
    FROM Categories AS c 

    UNION ALL 

    SELECT c.CatRank 
      ,ROW_NUMBER() OVER(PARTITION BY t.category ORDER BY t.Value) 
      ,t.category 
      ,t.ID 
      ,CAST(t.value AS VARCHAR(100)) 
      ,t.[desc] 
    FROM @YourTable AS t 
    INNER JOIN Categories AS c ON t.category=c.category 
) 
SELECT category,Value,[desc] 
FROM Grouped 
ORDER BY CatRank,ValRank 

Результат

category Value desc 
**A**  
A   10  text1 
A   11  text11 
**B**  
B   20  text20 
B   21  text21 
**C**  
C   30  text30 

 Смежные вопросы

  • Нет связанных вопросов^_^