Есть ли какой-либо способ поместить подзапрос в список столбцов SQL-запроса

#sql #sql-server #tsql

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

Вопрос:

Я пытаюсь написать SQL-запрос, содержащий список столбцов, который генерируется из другого SQL-запроса. Я работаю в среде Microsoft SQL Server Management Studio.

Это SQL-запрос, который получает список столбцов

 SELECT COLUMN_NAME  FROM INFORMATION_SCHEMA.COLUMNS  WHERE TABLE_NAME = 'table_name'  

Он возвращает следующее

 | | COLUMN_NAME | | -------- | -------------- | | 1 | name1 | | 2 | name2 | | 3 | name3 |  

Это SQL-запрос, который у меня сейчас есть, и он хорошо работает

 SELECT DISTINCT name1, name2  FROM [table_catalog].[table_schema].[table_name]  

Вот что он возвращает

 | | name1 |name2 | | -------- | -------------- |-------------- | | 1 | value1 |a1 | | 2 | value2 |a2 | | 3 | value3 |a3 | | 3 | value4 |a1 |  

Что я хотел бы сделать, так это получить таблицу, содержащую все столбцы только из первой таблицы, вот так

 | | name1 |name2 |name3 | | -------- | -------------- |-------------- |-------------- | | 1 | value1 |a1 |b1 | | 2 | value2 |a2 |b2 | | 3 | value3 |a3 |b1 | | 3 | value4 |a1 |b2 |  

Это моя попытка до сих пор

 SELECT DISTINCT  (SELECT COLUMN_NAME   FROM INFORMATION_SCHEMA.COLUMNS   WHERE TABLE_NAME = 'table_name')  FROM   [table_catalog].[table_schema].[table_name]  

Это работает не так, как ожидалось, я также пытался использовать CLE и некоторые другие способы сделать это. Однако ни один из них не работает. Похоже, что не многие люди делали такого рода запросы после того, как я провел некоторое исследование в Интернете, интересно, есть ли другой способ сделать это? Что я сделал не так?

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

1. Хотя ваш вопрос неясен, похоже, что вы ищете динамический sql

2. Я полагаю, что мне, возможно, потребуется написать цикл for для создания списка столбцов?

3. Какова логика для последней колонки name3 ? Как вы ассоциируетесь name1 name2 с этими ценностями ?

4. «Я думаю, мне, возможно, придется написать цикл for» , очень маловероятно. SQL-это язык, основанный на множествах, и если вы пишете цикл, вы, вероятно, делаете это неправильно.

5. Привет, Белка. Это опечатка. Я их починил. Это случайные значения для каждого столбца.

Ответ №1:

Для этого вам придется использовать динамический sql.
вот небольшой пошаговый пример. Полный код будет в конце.

Сначала нам нужно получить имена столбцов в переменной. Мы хотим, чтобы эта переменная была заполнена всеми столбцами из table_name и разделена запятой. Вот почему мы используем for XML path('') Это stuff для удаления первой запятой.

 declare @ColNames varchar(max)  select @ColNames = stuff(( select ', '   column_name  from INFORMATION_SCHEMA.COLUMNS  where table_name = 'table_name'  for XML path('')  ), 1, 2, '')  

Содержимое переменной @ColNames будет выглядеть следующим образом

 name1, name2, name3  

с помощью этого мы можем построить наш оператор sql, также в переменной

 declare @sql varchar(max) set @sql = 'select '   @ColNames   ' from table_name'  

и, наконец, мы выполняем его

 exec(@sql)  

Это должно дать вам необходимые результаты.

И, конечно, вы также можете поместить имя таблицы table_name в переменную, что сделает все это немного более гибким.
Вот полный код:

 declare @TableName varchar(100) = 'SomeTableName'  declare @ColNames varchar(max) select @ColNames = stuff(( select ', '   column_name  from INFORMATION_SCHEMA.COLUMNS  where table_name = @TableName  for XML path('')  ), 1, 2, '')  declare @sql varchar(max) set @sql = 'select '   @ColNames   ' from '   @TableName  exec(@sql)  

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

1. Привет, спасибо. Если этот ответ решит вашу проблему, пожалуйста, рассмотрите возможность повышения голоса и/или примите это как ответ. Теперь о 1, 2 в команде «Материал». Выбор для XML приведет к следующему результату: , name1, name2, name3 и «1, 2″ означает, что я хочу из позиции 1 заменить 2 символа на», так что результат теперь name1, name2, name3

2. Привет, ГвидоГ, большое тебе спасибо за твой ответ. Это именно то, что я ищу. Однако то, что я запускаю код, работает не так, как ожидалось. Он не показывает таблицу, которую я ищу. Поэтому я проверил ваш код и попытался распечатать(@ColNames), но ничего не распечатал. Интересно, есть ли что-нибудь, что мне нужно отредактировать, кроме @TableName?

3. это работает для меня, вы скопировали/вставили код точно так же ? И да, вам нужно только отредактировать переменную TableName

4. Спасибо за ваш ответ. Я поддержал ваш ответ. Спасибо и за ваше объяснение тоже. Это действительно полезно.

5. Я только что попробовал это в MSSM, и это работает, я получаю результат без проблем