varias - SQL excluye una columna usando SELECT*[excepto columnA] FROM tableA?
sql diferente de varios valores (30)
Todos sabemos que para seleccionar todas las columnas de una tabla, podemos usar
SELECT * FROM tableA
¿Hay alguna forma de excluir columnas de una tabla sin especificar todas las columnas?
SELECT * [except columnA] FROM tableA
La única forma que conozco es especificar manualmente todas las columnas y excluir la columna no deseada. Esto requiere mucho tiempo, por lo que estoy buscando formas de ahorrar tiempo y esfuerzo, así como un futuro mantenimiento en caso de que la tabla tenga más / menos columnas.
¡Gracias!
¿Hay alguna forma de excluir columnas de una tabla sin especificar todas las columnas?
Usando el SQL declarativo de la forma habitual, no
Creo que su sintaxis propuesta es digna y buena. De hecho, el lenguaje de base de datos relacional ''Tutorial D'' tiene una sintaxis muy similar donde las palabras clave ALL BUT
están seguidas de un conjunto de atributos (columnas).
Sin embargo, SELECT *
SQL ya recibe muchas críticas (la respuesta de @ Guffa aquí es una objeción típica), por lo que no creo que SELECT ALL BUT
entrará en el estándar de SQL en el corto plazo.
Creo que el mejor ''trabajo'' es crear una VIEW
con solo las columnas que desea luego SELECT * FROM ThatView
.
¿No sería más simple hacer esto?
sp_help <table_name>
-Haga clic en la columna ''Nombre de columna''> Copiar> Pegar (crea una lista vertical) en una ventana Nueva consulta y escriba comas delante de cada valor de columna ... comente las columnas que no desea ... mucho menos escribiendo que cualquier código ofrecido aquí y aún manejable.
A veces el mismo programa debe manejar diferentes estructuras de base de datos. Así que no pude usar una lista de columnas en el programa para evitar errores en declaraciones select
.
*
Me da todos los campos opcionales. Verifico si los campos existen en la tabla de datos antes del uso. Esta es mi razón para usar *
en select
.
Así es como manejo los campos excluidos:
Dim da As New SqlDataAdapter("select * from table", cn)
da.FillSchema(dt, SchemaType.Source)
Dim fieldlist As String = ""
For Each DC As DataColumn In DT.Columns
If DC.ColumnName.ToLower <> excludefield Then
fieldlist = fieldlist & DC.Columnname & ","
End If
Next
Básicamente, no puede hacer lo que le gustaría, pero puede obtener las herramientas adecuadas para ayudarlo a hacer las cosas un poco más fáciles.
Si observa la solicitud de SQL de Red-Gate, puede escribir "SELECT * FROM MyTable", y luego mover el cursor hacia atrás después de "*", y presionar <TAB> para expandir la lista de campos y eliminar aquellos pocos campos que haya no necesito
No es una solución perfecta, ¡pero sí una buena! :-) Lástima que el Intellisense de MS SQL Server Management Studio aún no sea lo suficientemente inteligente como para ofrecer esta característica .......
Bagazo
Bueno, es una práctica recomendada común especificar qué columnas desea, en lugar de simplemente especificar *. Por lo tanto, solo debe indicar qué campos desea que su selección regrese.
Como han dicho los demás, no hay manera de hacer esto, pero si estás usando el servidor Sql, un truco que utilizo es cambiar la salida a separada por comas, entonces hazlo.
select top 1 * from table
y cortar toda la lista de columnas de la ventana de salida. Luego, puede elegir qué columnas desea sin tener que escribirlas todas.
Dependiendo del tamaño de su tabla, puede exportarlo a Excel y transponerlo para tener una nueva tabla en la que las columnas de la tabla original serán las filas en la nueva tabla. Luego llévelo nuevamente a su base de datos SQL y seleccione las filas según la condición e insértelas en otra tabla nueva. Finalmente, exporte esta tabla más nueva a Excel y realice otra transposición para obtener la tabla deseada y devolverla a su base de datos SQL.
No estoy seguro de si se puede hacer la transposición dentro de la base de datos SQL, si es así, entonces será aún más fácil.
Jeff
En SQL Management Studio, puede expandir las columnas en el Explorador de objetos y luego arrastrar el elemento del árbol Columns
a una ventana de consulta para obtener una lista de columnas separadas por comas.
En SSMS hay una forma más fácil con IntelliSense y Aliasing . Prueba esto
- Haga clic derecho en el editor de texto y asegúrese de que IntelliSense esté habilitado.
- Escriba la consulta con un alias [SELECT t. * FROM nombre de tabla t].
- Vaya al texto t. * Y elimine el * , y SSMS mostrará automáticamente las columnas de la tabla con alias.
En resumen, no puede hacerlo, pero no estoy de acuerdo con todos los comentarios anteriores, existen "hay" escenarios en los que puede usar legítimamente un * Cuando crea una consulta anidada para seleccionar un rango específico de una lista completa (como paginación) ¿por qué en el mundo querría especificar cada columna en la declaración de selección externa cuando lo haya hecho en la interna?
Eso es lo que uso a menudo para este caso:
declare @colnames varchar(max)=''''
select @colnames=@colnames+'',''+name from syscolumns where object_id(tablename)=id and name not in (column3,column4)
SET @colnames=RIGHT(@colnames,LEN(@colnames)-1)
@colnames
parece a column1,column2,column5
Esto no ahorrará tiempo al cargar desde la base de datos. Pero, siempre se puede desactivar la columna que no desea en la matriz en la que está ubicado. Tenía varias columnas en una tabla pero no quería una en particular. Era demasiado perezoso para escribirlos todos en la declaración SELECT.
$i=0;
$row_array = array();
while($row = mysqli_fetch_assoc($result)){
$row_array[$i]=$row;
unset($row_array[$i][''col_name'']);
$i++;
}
Estoy de acuerdo con todos ... pero si fuera a hacer algo como esto, podría hacerlo de esta manera:
/* Get the data into a temp table */
SELECT * INTO #TempTable
FROM YourTable
/* Drop the columns that are not needed */
ALTER TABLE #TempTable
DROP COLUMN ColumnToDrop
/* Get results and drop temp table */
SELECT * FROM #TempTable
DROP TABLE #TempTable
Haga clic derecho en la tabla en el Explorador de objetos, seleccione 1000 filas superiores
Enumera todas las columnas y no *. Luego retire la (s) columna (s) no deseada (s). Debería ser mucho más rápido que escribirlo tú mismo.
Luego, cuando creas que esto es demasiado trabajo, obtén la solicitud de SQL de Red Gate, y escribe ssf desde tbl, ve a la pestaña * y haz clic nuevamente.
La forma automatizada de hacer esto en SQL (SQL Server) es:
declare @cols varchar(max), @query varchar(max);
SELECT @cols = STUFF
(
(
SELECT DISTINCT ''], ['' + name
FROM sys.columns
where object_id = (
select top 1 object_id from sys.objects
where name = ''MyTable''
)
and name not in (''ColumnIDontWant1'', ''ColumnIDontWant2'')
FOR XML PATH('''')
), 1, 2, ''''
) + '']'';
SELECT @query = ''select '' + @cols + '' from MyTable'';
EXEC (@query);
La mejor manera de resolver esto es usando la vista, puede crear la vista con las columnas requeridas y recuperar los datos de la misma.
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)
Lo hice así y funciona bien (versión 5.5.41):
# prepare column list using info from a table of choice
SET @dyn_colums = (SELECT REPLACE(
GROUP_CONCAT(`COLUMN_NAME`), '',column_name_to_remove'','''')
FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE
`TABLE_SCHEMA`=''database_name'' AND `TABLE_NAME`=''table_name'');
# set sql command using prepared columns
SET @sql = CONCAT("SELECT ", @dyn_colums, " FROM table_name");
# prepare and execute
PREPARE statement FROM @sql;
EXECUTE statement;
No conozco ninguna base de datos que admita esto (SQL Server, MySQL, Oracle, PostgreSQL). Definitivamente no es parte de los estándares SQL, así que creo que debe especificar solo las columnas que desea.
Por supuesto, podría construir su declaración SQL de forma dinámica y hacer que el servidor la ejecute. Pero esto abre la posibilidad de inyección SQL.
No, no hay forma de hacerlo, y no hay una buena razón para hacerlo.
Al seleccionar datos, nunca debe utilizar *
, siempre debe especificar los campos que desee. El motivo es que desea que la consulta funcione de la misma manera incluso si luego agrega otro campo a la tabla. También especifica el orden de los campos en el resultado para que la reorganización de los campos en la tabla no cambie el resultado.
Lo mismo se aplicaría, por supuesto, a * except
si era posible hacerlo.
No, no hay manera de hacer esto. Tal vez pueda crear vistas personalizadas si eso es factible en su situación.
EDITAR Puede ser si su base de datos admite la ejecución de sql dinámico u podría escribir un SP y pasar las columnas que no desea ver y dejar que cree la consulta de forma dinámica y le devuelva el resultado. Creo que esto es factible en SQL Server al menos
No.
La mejor práctica de mantenimiento ligero es especificar solo las columnas requeridas.
Al menos 2 razones:
- Esto hace que su contrato entre el cliente y la base de datos sea estable. Los mismos datos, cada vez.
- Rendimiento, cubriendo índices.
Edición (julio de 2011):
Si arrastra desde el Explorador de objetos el nodo Columns
de una tabla, coloca una lista de columnas CSV en la Ventana de consulta para que logre uno de sus objetivos.
Puede crear una vista que tenga las columnas que desea seleccionar, luego puede seleccionar * desde la vista ...
Puede obtener SQL Complete de devart.com, que no solo expande el comodín * como lo hace el SQL Prompt de Red Gate (como se describe en la respuesta de cairnz), sino que también proporciona un selector de columnas desplegable con casillas de verificación en las que puede marcar todas las Las columnas que desee en la lista de selección se insertarán automáticamente para usted (y si desmarca una columna, se eliminará automáticamente de la lista de selección).
Sé que esto es un poco viejo, pero acabo de encontrarme con el mismo problema y estaba buscando una respuesta. Luego tuve un desarrollador senior que me mostró un truco muy simple.
Si está utilizando el editor de consultas de Management Studio, expanda la base de datos, luego expanda la tabla que está seleccionando para que pueda ver la carpeta de columnas.
En su declaración de selección, simplemente resalte la carpeta de columnas a la que se hace referencia arriba y arrástrela y suéltela en la ventana de consulta. Pegará todas las columnas de la tabla, luego simplemente eliminará la columna de identidad de la lista de columnas ...
Sí, es posible (pero no recomendado).
CREATE TABLE contact (contactid int, name varchar(100), dob datetime)
INSERT INTO contact SELECT 1, ''Joe'', ''1974-01-01''
DECLARE @columns varchar(8000)
SELECT @columns = ISNULL(@columns + '', '','''') + QUOTENAME(column_name)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = ''contact'' AND COLUMN_NAME <> ''dob''
ORDER BY ORDINAL_POSITION
EXEC (''SELECT '' + @columns + '' FROM contact'')
Explicación del código :
- Declare una variable para almacenar una lista de nombres de columna separados por comas. Esto por defecto es NULL.
- Use una vista del sistema para determinar los nombres de las columnas en nuestra tabla.
- Use
SELECT @variable = @variable + ... FROM
para concatenar los nombres de columna. Este tipo deSELECT
no devuelve un conjunto de resultados. Este es quizás un comportamiento no documentado pero funciona en todas las versiones de SQL Server. Como alternativa, puede usarSET @variable = (SELECT ... FOR XML PATH(''''))
para concatenar cadenas. - Use la función
ISNULL
para anteponer una coma solo si este no es el nombre de la primera columna. Utilice la funciónQUOTENAME
para admitir espacios y puntuación en los nombres de columna. - Utilice la cláusula
WHERE
para ocultar las columnas que no queremos ver. - Utilice
EXEC (@variable)
, también conocido como SQL dinámico , para resolver los nombres de columna en tiempo de ejecución. Esto es necesario porque no sabemos los nombres de las columnas en el momento de la compilación.
Si está utilizando SQL Server Management Studio, haga lo siguiente:
- Escriba el nombre de su tabla deseada y selecciónelo
- Presiona Alt + F1
- o / p muestra las columnas en la tabla.
- Seleccione las columnas deseadas
- Copia y pega esos en tu consulta de selección
- Dispara la consulta.
Disfrutar.
Si estamos hablando de procedimientos, funciona con este truco para generar una nueva consulta y EJECUTAR INMEDIATAMENTE :
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'');
Si no desea escribir cada nombre de columna manualmente, puede usar Script Table As
haciendo clic derecho en la tabla o ver en SSMS de esta manera:
Luego obtendrá una consulta de selección completa en la ventana del nuevo editor de consultas y luego eliminará las columnas no deseadas como esta:
Hecho
Un colega aconsejó una buena alternativa:
- Seleccione SELECT INTO en su consulta anterior (en la que genera u obtiene los datos) en una tabla (que eliminará cuando termine). Esto creará la estructura para usted.
- Hacer un script como CREAR para nueva ventana de consulta.
- Eliminar las columnas no deseadas. Formatee las columnas restantes en un trazador de líneas 1 y péguelas como su lista de columnas.
- Borra la tabla que creaste.
Hecho...
Esto nos ayudó mucho.
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)
ACTUALIZAR:
También puede crear un procedimiento almacenado para encargarse de esta tarea si lo usa con más frecuencia. En este ejemplo, he utilizado el STRING_SPLIT() que está disponible en SQL Server 2016+, pero si lo necesita, hay muchos ejemplos de cómo crearlo manualmente en 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
Y luego solo
EXEC [usp_select_without]
@table_name = N''Test_Table'',
@list_of_columns_excluded = N''ID, Date, Name'';