Выберите не пустые столбцы в качестве строки, разделенной запятыми, из динамического SQL - PullRequest
2 голосов
/ 05 апреля 2019

Я стараюсь изо всех сил избегать использования курсоров. В переменной nvarchar есть список столбцов через запятую, который выглядит следующим образом:

@columnList = 'col1,col2,col5'

Есть таблица с множеством столбцов varchar:

myTable: [col1],[col2],[col3],[col4],[col5],[col6],[col7]

Вот как я выбираю данные, используя динамический sql:

exec ('select ' + @columnList + ' from myTable')

Этот запрос возвращает следующие результаты:

[col1], [col2] , [col5]
 null , "txt1" ,  null
"txt2",  null  ,  null
 null , "txt3" , "txt4"

Вот что мне нужно получить:

@resultList = "txt1,txt2,txt3,txt4"

Как выбрать строку через запятую, содержащую только ненулевые значения? Я знаю, как преобразовать таблицу в строку через запятую, поэтому получаю что-то вроде:

 [column]
  "txt1"
  "txt2"
  "txt3"
  "txt4"

Тоже хорошо. Какие-либо предложения? Не стесняйтесь предлагать базовый подход, я не ожидаю, что вы напишите реальный код для меня.

Ответы [ 3 ]

2 голосов
/ 05 апреля 2019

Вы можете использовать решение, подобное следующему, используя просто REPLACE для создания SQL-запроса:

DECLARE @columnList VARCHAR(100)
SET @columnList = 'col1,col2,col5'
SET @columnList = REPLACE(@columnList, ',', ' AS colName FROM myTable UNION ALL SELECT ');

EXEC('SELECT * FROM (SELECT ' + @columnList + ' AS colName FROM myTable)t WHERE NOT t.colName IS NULL');

Вы также можете использовать решение, используя UNPIVOT:

DECLARE @columnList VARCHAR(100);
SET @columnList = 'col1,col2,col5';

EXEC('SELECT colName FROM (SELECT ' + @columnList + ' FROM myTable) t1 UNPIVOT (colName FOR columnNames IN (' + @columnList + ')) AS t2');

демо на dbfiddle.uk

0 голосов
/ 05 апреля 2019

Это будет работать для SQL Server 2017, в более ранней версии STRING_AGG использование следует заменить на Решение на основе XML .

Вы можете сначала объединить свои результаты в одну строку, а затем использовать STRING_AGG, чтобы объединить их в одну строку:

;with t as
(
SELECT * FROM (VALUES
   (null  , 'txt1' ,  null),
   ('txt2',  null  ,  null),
   (null  , 'txt3' , 'txt4')) x(col1, col2, col5) 
)
SELECT STRING_AGG(STUFF(CONCAT(',' + col1, ',' + col2, ',' + col5), 1, 1, ''), ',')
  FROM t

CTE только для демонстрации, вы можете просто сделать это в своем динамическом запросе:

DECLARE @columnList NVARCHAR(MAX) = 'col1,col2,col5'
DECLARE @query NVARCHAR(MAX) = ''
SELECT @query = 'SELECT STRING_AGG(STUFF(CONCAT('','' + ' + REPLACE(@columnList, ',', ', '','' + ') + '), 1, 1, ''''), '','') from mytable'

EXEC sp_executesql @query

Рабочий пример для dbfiddle

0 голосов
/ 05 апреля 2019

Поскольку вы упомянули, что вы уже знаете, как объединить в запятую, вот как можно разворачивать таблицу с помощью перекрестного применения:

select unpivoted.*
from myTable
cross apply
( values
     ('col1',col2)
    ,('col2',col2)
    ,('col3',col3) -- etc
)unpivoted(colname,colval)
...