SQL исключает столбец, используя SELECT * [кроме columnA] FROM tableA? - PullRequest
626 голосов
/ 08 апреля 2009

Мы все знаем, что для выбора всех столбцов из таблицы мы можем использовать

SELECT * FROM tableA

Есть ли способ исключить столбцы из таблицы без указания всех столбцов?

SELECT * [except columnA] FROM tableA

Единственный известный мне способ - вручную указать все столбцы и исключить ненужные столбцы. Это действительно отнимает много времени, поэтому я ищу способы сэкономить время и усилия на этом, а также на будущем обслуживании, если в таблице будет больше / меньше столбцов.

спасибо!

Ответы [ 36 ]

7 голосов
/ 08 апреля 2009

нет, нет способа сделать это. возможно, вы можете создать собственные представления, если это возможно в вашей ситуации

РЕДАКТИРОВАТЬ Может быть, если ваша БД поддерживает выполнение динамического SQL, вы можете написать SP и передать столбцы, которые вы не хотите видеть, и позволить ему динамически создавать запрос и возвращать результат в вы. Я думаю, что это выполнимо в SQL Server по крайней мере

6 голосов
/ 16 октября 2017
DECLARE @SQL VARCHAR(max), @TableName sysname = 'YourTableName'

SELECT @SQL = COALESCE(@SQL + ', ', '') + Name 
FROM sys.columns
WHERE OBJECT_ID = OBJECT_ID(@TableName)
AND name NOT IN ('Not This', 'Or that');

SELECT @SQL = 'SELECT ' + @SQL + ' FROM ' + @TableName

EXEC (@SQL)

UPDATE:

Вы также можете создать хранимую процедуру для решения этой задачи, если будете использовать ее чаще. В этом примере я использовал встроенную STRING_SPLIT () , которая доступна на SQL Server 2016+, но если вам нужно, есть множество примеров того, как создать его вручную на SO.

CREATE PROCEDURE [usp_select_without]
@schema_name sysname = N'dbo',
@table_name sysname,
@list_of_columns_excluded nvarchar(max),
@separator nchar(1) = N','
AS
BEGIN
 DECLARE 
 @SQL nvarchar(max),
 @full_table_name nvarchar(max) = CONCAT(@schema_name, N'.', @table_name);

 SELECT @SQL = COALESCE(@SQL + ', ', '') + QUOTENAME([Name])
 FROM sys.columns sc
 LEFT JOIN STRING_SPLIT(@list_of_columns_excluded, @separator) ss ON sc.[name] = ss.[value]
 WHERE sc.OBJECT_ID = OBJECT_ID(@full_table_name, N'u')
 AND ss.[value] IS NULL;

 SELECT @SQL = N'SELECT ' + @SQL + N' FROM ' + @full_table_name;
 EXEC(@SQL)
END

А потом просто:

EXEC [usp_select_without] 
@table_name = N'Test_Table',
@list_of_columns_excluded = N'ID, Date, Name';
6 голосов
/ 06 мая 2010

Таким образом, вы не можете сделать это, но я не согласен со всеми комментариями выше, есть "сценарии", в которых вы можете законно использовать * Когда вы создаете вложенный запрос, чтобы выбрать определенный диапазон из целого списка (например, подкачки страниц), почему в мире нужно указывать каждый столбец во внешнем операторе выбора, когда вы сделали это во внутреннем?

5 голосов
/ 21 мая 2014

Если мы говорим о процедурах, он работает с этим трюком, чтобы сгенерировать новый запрос, и EXECUTE IMMEDIATE it:

SELECT LISTAGG((column_name), ', ') WITHIN GROUP (ORDER BY column_id)
INTO var_list_of_columns
FROM ALL_TAB_COLUMNS
WHERE table_name = 'PUT_HERE_YOUR_TABLE'
AND column_name NOT IN ('dont_want_this_column','neither_this_one','etc_column');
5 голосов
/ 24 марта 2011

Есть ли способ исключить столбцы из таблицы без указания все столбцы?

Обычным способом используется декларативный SQL, нет.

Я думаю, что предложенный вами синтаксис достоин и хорош. Фактически, язык реляционной базы данных «Учебник D» имеет очень похожий синтаксис, где после ключевых слов ALL BUT следует набор атрибутов (столбцов).

Тем не менее, SELECT * в SQL уже очень сильно ошибается (ответ @ Guffa здесь - типичное возражение), поэтому я не думаю, что SELECT ALL BUT попадет в стандарт SQL в ближайшее время.

Я думаю, что лучшим «обходным путем» является создание VIEW только с теми столбцами, которые вам нужны, тогда SELECT * FROM ThatView.

3 голосов
/ 22 мая 2014

Я знаю, что это немного старо, но я только что столкнулся с той же проблемой и искал ответ. Затем старший разработчик показал мне очень простой трюк.

Если вы используете редактор запросов Management Studio, разверните базу данных, затем разверните таблицу, из которой вы выбираете, чтобы увидеть папку столбцов.

В вашем операторе select просто выделите указанную выше папку столбцов и перетащите ее в окно запроса. Он вставит все столбцы таблицы, а затем просто удалит идентификационный столбец из списка столбцов ...

3 голосов
/ 08 апреля 2009

Я не знаю ни одной базы данных, которая бы поддерживала это (SQL Server, MySQL, Oracle, PostgreSQL). Это определенно не является частью стандартов SQL, поэтому я думаю, что вы должны указывать только те столбцы, которые вам нужны.

Конечно, вы можете динамически построить оператор SQL и заставить его выполнить сервер. Но это открывает возможность для внедрения SQL-кода.

2 голосов
/ 08 апреля 2009

Что ж, обычно рекомендуется указывать, какие столбцы вы хотите, вместо того, чтобы просто указывать *. Таким образом, вы должны просто указать, какие поля вы хотите, чтобы ваш выбор возвращал.

2 голосов
/ 02 февраля 2012

Колледж посоветовал хорошую альтернативу:

  • ВЫБЕРИТЕ INTO в предыдущем запросе (где вы генерируете или получаете данные из) в таблицу (которую вы удалите, когда закончите). Это будет создать структуру для вас.
  • Сделать скрипт как CREATE для нового запроса окно.
  • Удалите ненужные столбцы. Отформатируйте оставшиеся столбцы в 1 вкладыш и вставьте в качестве списка столбцов.
  • Удалить таблицу, которую вы создано.

Совершено ...

Это нам очень помогло.

2 голосов
/ 30 июня 2016

Лучший способ решить эту проблему - использовать представление, вы можете создать представление с необходимыми столбцами и извлечь из него данные

example

mysql> SELECT * FROM calls;
+----+------------+---------+
| id | date       | user_id |
+----+------------+---------+
|  1 | 2016-06-22 |       1 |
|  2 | 2016-06-22 |    NULL |
|  3 | 2016-06-22 |    NULL |
|  4 | 2016-06-23 |       2 |
|  5 | 2016-06-23 |       1 |
|  6 | 2016-06-23 |       1 |
|  7 | 2016-06-23 |    NULL |
+----+------------+---------+
7 rows in set (0.06 sec)

mysql> CREATE VIEW C_VIEW AS
    ->     SELECT id,date from calls;
Query OK, 0 rows affected (0.20 sec)

mysql> select * from C_VIEW;
+----+------------+
| id | date       |
+----+------------+
|  1 | 2016-06-22 |
|  2 | 2016-06-22 |
|  3 | 2016-06-22 |
|  4 | 2016-06-23 |
|  5 | 2016-06-23 |
|  6 | 2016-06-23 |
|  7 | 2016-06-23 |
+----+------------+
7 rows in set (0.00 sec)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...