Nous savons tous que pour sélectionner toutes les colonnes d’une table, nous pouvons utiliser
SELECT * FROM tableA
Est-il possible d'exclure une ou plusieurs colonnes d'une table sans spécifier toutes les colonnes?
SELECT * [except columnA] FROM tableA
Le seul moyen que je connaisse consiste à spécifier manuellement toutes les colonnes et à exclure la colonne non désirée. Cela prend beaucoup de temps, je cherche donc des moyens de gagner du temps et des efforts, ainsi que la maintenance future si le tableau comporte plus/moins de colonnes.
merci!
Je suis d'accord avec tout le monde ... mais si j'allais faire quelque chose comme ça, je pourrais le faire de cette façon:
/* 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
Non.
La meilleure pratique en matière de maintenance est de spécifier uniquement les colonnes requises.
Au moins 2 raisons:
Edit (juillet 2011):
Si vous faites glisser le nœud Columns
d'une table à partir de l'explorateur d'objets, une liste CSV de colonnes de la fenêtre de requête vous permet d'atteindre l'un de vos objectifs
La manière automatisée de le faire en SQL (SQL Server) est la suivante:
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);
Si vous ne voulez pas écrire chaque nom de colonne manuellement, vous pouvez utiliser Script Table As
en cliquant avec le bouton droit de la souris sur table ou view dans SSMS comme ceci:
Ensuite, vous obtiendrez la requête entière dans la fenêtre New Query Editor, puis supprimerez les colonnes non désirées comme ceci:
Terminé
Vous pouvez créer une vue contenant les colonnes que vous souhaitez sélectionner, puis vous pouvez simplement sélectionner * dans la vue ...
Oui c'est possible (mais pas recommandé).
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')
Explication du code :
SELECT @variable = @variable + ... FROM
pour concaténer les noms de colonnes Ce type de SELECT
ne renvoie pas de jeu de résultats. Ceci est peut-être un comportement non documenté mais fonctionne dans toutes les versions de SQL Server. Vous pouvez également utiliser SET @variable = (SELECT ... FOR XML PATH(''))
pour concaténer des chaînes.ISNULL
pour insérer une virgule uniquement s'il ne s'agit pas du premier nom de colonne Utilisez la fonction QUOTENAME
pour prendre en charge les espaces et la ponctuation dans les noms de colonne.WHERE
pour masquer les colonnes que nous ne voulons pas voir.EXEC (@variable)
, également appelé dynamic SQL, pour résoudre les noms de colonnes Au moment de l'exécution. Cela est nécessaire car nous ne connaissons pas les noms des colonnes au moment de la compilation.Comme les autres l’ont dit, il n’existe aucun moyen de le faire, mais si vous utilisez Sql Server, une astuce que j’utilise consiste à modifier la sortie en virgule séparée,
select top 1 * from table
et couper toute la liste des colonnes de la fenêtre de sortie. Ensuite, vous pouvez choisir les colonnes que vous voulez sans avoir à toutes les taper.
En gros, vous ne pouvez pas faire ce que vous voulez, mais vous pouvez vous procurer les bons outils pour vous aider à rendre les choses un peu plus faciles.
Si vous consultez l'invite SQL de Red-Gate , vous pouvez taper "SELECT * FROM MyTable", puis déplacer le curseur après le "*" et appuyer sur <TAB> pour développer la liste des champs, puis supprimer ces quelques champs dont vous n'avez pas besoin.
Ce n'est pas une solution parfaite - mais une sacrément bonne! :-) Dommage, Intellisense de MS SQL Server Management Studio n’est toujours pas assez intelligent pour offrir cette fonctionnalité .......
Marc
Dans SQL Management Studio, vous pouvez développer les colonnes dans l'Explorateur d'objets, puis faire glisser l'élément d'arborescence Columns
dans une fenêtre de requête pour obtenir une liste de colonnes séparée par des virgules.
non, il n'y a pas moyen de faire ça. peut-être pouvez-vous créer des vues personnalisées si cela est réalisable dans votre cas
EDITPeut-être si votre base de données prend en charge l'exécution de sql dynamique, vous pouvez écrire un SP et transmettre les colonnes à ne pas vouloir voir. Laissez-le créer la requête de manière dynamique et renvoyer le résultat. à toi. Je pense que cela est faisable dans SQL Server au moins
Si vous utilisez SQL Server Management Studio, procédez comme suit:
Prendre plaisir.
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)
METTRE À JOUR:
Vous pouvez également créer une procédure stockée pour prendre en charge cette tâche si vous l'utilisez plus souvent . Dans cet exemple, j'ai utilisé la fonction intégrée STRING_SPLIT () disponible sur SQL Server 2016 +,. .mais si vous en avez besoin, il existe de nombreux exemples sur la manière de le créer manuellement sur 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
Et puis juste:
EXEC [usp_select_without]
@table_name = N'Test_Table',
@list_of_columns_excluded = N'ID, Date, Name';
En résumé, vous ne pouvez pas le faire, mais je suis en désaccord avec tous les commentaires ci-dessus, il existe des scénarios dans lesquels vous pouvez légitimement utiliser un * Lorsque vous créez une requête imbriquée afin de sélectionner une plage spécifique dans une liste complète (pagination, par exemple), pourquoi dans le monde voudrait-il spécifier chaque colonne de l'instruction de sélection externe alors que vous l'avez faite à l'intérieur?
Existe-t-il un moyen d'exclure une ou plusieurs colonnes d'une table sans spécifier toutes les colonnes?
Utiliser le SQL déclaratif de la manière habituelle, non.
Je pense que votre syntaxe proposée est digne et bonne. En fait, le langage de base de données relationnelle 'Tutorial D' a une syntaxe très similaire, les mots-clés ALL BUT
étant suivis d'un ensemble d'attributs (colonnes).
Cependant, le code SELECT *
de SQL est déjà très critiqué (la réponse de @ Guffa étant une objection typique), je ne pense donc pas que SELECT ALL BUT
entrera dans le standard SQL de si tôt.
Je pense que la meilleure solution consiste à créer une VIEW
avec uniquement les colonnes souhaitées, puis SELECT * FROM ThatView
.
Si nous parlons de procédures, cette astuce permet de générer une nouvelle requête et 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');
Je ne connais aucune base de données qui le supporte (SQL Server, MySQL, Oracle, PostgreSQL). Cela ne fait certainement pas partie des standards SQL, je pense donc que vous devez spécifier uniquement les colonnes souhaitées.
Vous pouvez bien sûr construire votre instruction SQL de manière dynamique et le faire exécuter par le serveur. Mais cela ouvre la possibilité d'injection SQL.
Je sais que c'est un peu vieux, mais je venais de rencontrer le même problème et je cherchais une réponse. Ensuite, un développeur senior m'a montré un truc très simple.
Si vous utilisez l'éditeur de requête de Management Studio, développez la base de données, puis développez le tableau que vous avez sélectionné pour que vous puissiez voir le dossier Colonnes.
Dans votre instruction select, sélectionnez simplement le dossier des colonnes référencées ci-dessus, puis faites-le glisser et déposez-le dans la fenêtre de requête. Il va coller toutes les colonnes de la table, puis simplement simplement supprimer la colonne d'identité de la liste des colonnes ...
Eh bien, il est de pratique courante de spécifier les colonnes de votre choix plutôt que de spécifier *. Vous devez donc simplement indiquer les champs que vous souhaitez que votre sélection retourne.
Un collègue a conseillé une bonne alternative:
Terminé...
Cela nous a beaucoup aidé.
Postgres sql a le moyen de le faire
veuillez vous reporter à: http://www.postgresonline.com/journal/archives/41-How-tow-toLECT-ALL-EXCEPT-some-columns-in-a-table.html
Le schéma d'information Hack Way
SELECT 'SELECT ' || array_to_string(ARRAY(SELECT 'o' || '.' || c.column_name
FROM information_schema.columns As c
WHERE table_name = 'officepark'
AND c.column_name NOT IN('officeparkid', 'contractor')
), ',') || ' FROM officepark As o' As sqlstmt
Le tableau ci-dessus pour mon exemple particulier - génère une instruction SQL ressemblant à ceci
SELECT o.officepark, o.owner, o.squarefootage DE officepark as o
Le meilleur moyen de résoudre ce problème consiste à utiliser view, vous pouvez créer une vue avec les colonnes requises et récupérer les données à partir
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)
Parfois, le même programme doit gérer différentes structures de base de données. Je ne pouvais donc pas utiliser une liste de colonnes dans le programme pour éviter les erreurs dans les instructions select
.
*
me donne tous les champs optionnels. Je vérifie si les champs existent dans la table de données avant utilisation. C'est la raison pour laquelle j'ai utilisé *
dans select
.
Voici comment je gère les champs exclus:
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
C'est ce que j'utilise souvent pour ce cas:
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
ressemble à column1,column2,column5
Faites un clic droit sur la table dans l'explorateur d'objets, sélectionnez les 1000 premières lignes
Il listera toutes les colonnes et pas *. Supprimez ensuite les colonnes indésirables. Devrait être beaucoup plus rapide que de le taper soi-même.
Ensuite, lorsque vous estimez que cela représente un peu trop de travail, procurez-vous l'invite SQL de Red Gate et tapez ssf à partir de tbl, accédez à * et cliquez à nouveau sur l'onglet.
La réponse proposée (procédure stockée) de BartoszX ne fonctionnait pas pour moi lorsque j'utilisais une vue plutôt qu'une table réelle.
Le crédit pour l'idée et le code ci-dessous (à l'exception de mon correctif) appartient à BartoszX.
Pour que cela fonctionne pour les tables ainsi que pour les vues, utilisez le code suivant:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[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)
AND ss.[value] IS NULL;
SELECT @SQL = N'SELECT ' + @SQL + N' FROM ' + @full_table_name;
EXEC(@SQL)
END
GO
Ne serait-il pas plus simple de faire ceci:
sp_help <table_name>
-Cliquez sur la colonne 'Nom_Colonne'> Copier> Coller (crée une liste verticale) dans une fenêtre Nouvelle requête et tapez des virgules devant chaque valeur de colonne ... commentez les colonnes que vous ne voulez pas ... beaucoup moins en tapant que n'importe quel code proposé ici et toujours gérable.
Je sais que cette question est ancienne, mais j'espère que cela pourra toujours être utile. La réponse est inspirée par une discussion de SQL Server Forums 1 . Vous pouvez en faire une procédure stockée. Il peut également être modifié pour en ajouter plusieurs, à l'exception des champs. La première colonne ne peut cependant pas être l'exception.
Declare @TBNAME sysname, @SQL NVARCHAR(MAX), @Exception VARCHAR(500)
SET @TBNAME = 'tableName'
SET @Exception = 'columnName'
SELECT @SQL = COALESCE(@SQL + '', '') + SQL FROM (
SELECT 'SELECT ' + COLUMN_NAME As SQL, 1 As SQLGroup
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TBNAME AND ORDINAL_POSITION = 1
UNION ALL
SELECT ', ' + COLUMN_NAME As SQL, 2 As SQLGroup
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TBNAME AND ORDINAL_POSITION <> 1 AND COLUMN_NAME <> @Exception
UNION ALL
SELECT ' FROM ' + TABLE_NAME As SQL, 3 As SQLGroup
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = @TBNAME
) As S
ORDER BY SQLGroup
SELECT @SQL --OR EXEC sp_executesql @SQL
Après avoir posté la solution ci-dessus, j'ai eu une meilleure idée:
DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = COALESCE(@SQL + ', ', ' ' ) + name from sys.columns where name <> 'colName' and object_id = (Select id from sysobjects where name = 'tblName')
SELECT @SQL = 'SELECT ' + @SQL + ' FROM ' + 'tblName'
EXEC sp_executesql @SQL
Vous pouvez obtenir SQL Complete à partir de devart.com, qui non seulement étend le caractère générique * comme le fait l’invite SQL de Red Gate (comme décrit dans la réponse de cairnz), mais fournit également une liste déroulante de sélecteurs de colonnes avec des cases à cocher permettant de vérifier toutes les informations. colonnes que vous voulez dans la liste de sélection et elles seront automatiquement insérées (et si vous décochez ensuite une colonne, elle sera automatiquement supprimée de la liste de sélection).
Cela ne vous fera pas gagner du temps lors du chargement depuis la base de données. Mais vous pouvez toujours désélectionner la colonne que vous ne voulez pas dans le tableau dans lequel elle est placée. J'avais plusieurs colonnes dans une table mais je ne voulais pas d'une en particulier. J'étais trop paresseux pour tout écrire dans l'instruction SELECT.
$i=0;
$row_array = array();
while($row = mysqli_fetch_assoc($result)){
$row_array[$i]=$row;
unset($row_array[$i]['col_name']);
$i++;
}
Je l'ai fait comme ça et ça marche très bien (version 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;
Si quelqu'un utilise MySql, comme moi, j'utilise ceci
CREATE TABLE TempTable AS SELECT * FROM #YourTable;
ALTER TABLE TempTable
DROP COLUMN #YourColumn;
SELECT * FROM TempTable;
DROP TABLE TempTable;
Dans SSMS, il existe un moyen plus simple avec IntelliSense et Aliasing . Essaye ça