Wir alle wissen, dass wir alle Spalten aus einer Tabelle auswählen können
SELECT * FROM tableA
Gibt es eine Möglichkeit, Spalten aus einer Tabelle auszuschließen, ohne alle Spalten anzugeben?
SELECT * [except columnA] FROM tableA
Die einzige Möglichkeit, die ich kenne, besteht darin, alle Spalten manuell anzugeben und die unerwünschte Spalte auszuschließen. Dies ist sehr zeitaufwändig, daher suche ich nach Möglichkeiten, Zeit und Aufwand zu sparen sowie zukünftige Wartungsarbeiten, falls die Tabelle mehr/weniger Spalten enthält.
vielen Dank!
Ich stimme jedem zu ... aber wenn ich so etwas machen würde, könnte ich es so machen:
/* 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
Nein.
Bei der Wartung von Light sollten Sie nur die erforderlichen Spalten angeben.
Mindestens zwei Gründe:
Bearbeiten (Juli 2011):
Wenn Sie aus dem Objekt-Explorer den Columns
-Knoten für eine Tabelle ziehen, wird eine CSV-Spaltenliste im Abfragefenster für Sie eingefügt, die eines Ihrer Ziele erreicht
Der automatisierte Weg, dies in SQL (SQL Server) zu tun, ist:
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);
Wenn Sie nicht jeden Spaltennamen manuell schreiben möchten, können Sie Script Table As
verwenden, indem Sie mit der rechten Maustaste auf table oder view in SSMS wie folgt klicken:
Sie erhalten dann eine vollständige Auswahlabfrage in New Query Editor Window und entfernen dann unerwünschte Spalten wie folgt:
Erledigt
Sie können eine Ansicht erstellen, deren Spalten Sie auswählen möchten. Dann können Sie einfach * aus der Ansicht auswählen ...
Ja, es ist möglich (aber nicht empfohlen).
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')
Erklärung des Codes :
SELECT @variable = @variable + ... FROM
, um die Spaltennamen Zu verketten. Dieser Typ von SELECT
gibt keine Ergebnismenge zurück. Dies ist möglicherweise undokumentiert, funktioniert jedoch in jeder Version von SQL Server. Alternativ können Sie SET @variable = (SELECT ... FOR XML PATH(''))
verwenden, um Strings zu verketten.ISNULL
, um ein Komma nur dann voranzustellen, wenn dies nicht der erste Spaltenname .__ ist Verwenden Sie die Funktion QUOTENAME
, um Leerzeichen und Satzzeichen in Spaltennamen zu unterstützen.WHERE
-Klausel, um Spalten auszublenden, die nicht angezeigt werden sollen.EXEC (@variable)
, auch bekannt als dynamic SQL, um die Spaltennamen Zur Laufzeit aufzulösen. Dies ist erforderlich, da wir die Spaltennamen zur Kompilierzeit nicht kennen.Wie die anderen schon gesagt haben, gibt es keine Möglichkeit, dies zu tun, aber wenn Sie SQL Server verwenden, ist ein Trick, den ich verwende, die Ausgabe in ein durch Kommas getrenntes Kommando zu ändern
select top 1 * from table
und schneiden Sie die gesamte Spaltenliste aus dem Ausgabefenster aus. Sie können dann die gewünschten Spalten auswählen, ohne sie alle eingeben zu müssen.
Grundsätzlich können Sie nicht das tun, was Sie möchten, aber Sie können die richtigen Tools erhalten, die Ihnen helfen, die Dinge etwas einfacher zu gestalten.
Wenn Sie sich Red-Gates SQL Prompt ansehen, können Sie "SELECT * FROM MyTable" eingeben, den Cursor nach "*" zurückbewegen und <TAB> drücken, um die Liste der Felder zu erweitern und zu entfernen Diese wenigen Felder brauchen Sie nicht.
Es ist keine perfekte Lösung - aber eine verdammt gute Lösung! :-) Schade, dass MS SQL Server Management Studio Intellisense immer noch nicht intelligent genug ist, um diese Funktion anzubieten .......
Marc
In SQL Management Studio können Sie die Spalten im Objekt-Explorer erweitern und dann das Baumelement Columns
in ein Abfragefenster ziehen, um eine durch Kommas getrennte Liste von Spalten zu erhalten.
nein, das ist unmöglich. Vielleicht können Sie benutzerdefinierte Ansichten erstellen, wenn dies in Ihrer Situation möglich ist
EDITMöglicherweise, wenn Ihre Datenbank die Ausführung von dynamischem SQL unterstützt. u könnte ein SP schreiben und die Spalten übergeben für dich. Ich denke, das ist in SQL Server atleast machbar
Wenn Sie SQL Server Management Studio verwenden, gehen Sie wie folgt vor:
Genießen.
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)
AKTUALISIEREN:
Sie können auch eine gespeicherte Prozedur erstellen, um diese Aufgabe zu erledigen, wenn Sie sie öfter verwenden .. In diesem Beispiel habe ich die eingebaute STRING_SPLIT () verwendet, die auf SQL Server 2016 + verfügbar ist. Aber wenn Sie brauchen, gibt es viele Beispiele, wie man es manuell auf SO erstellt.
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
Und dann einfach:
EXEC [usp_select_without]
@table_name = N'Test_Table',
@list_of_columns_excluded = N'ID, Date, Name';
Zusammenfassend können Sie es nicht tun, aber ich stimme dem gesamten obigen Kommentar nicht zu. Es gibt "Szenarien", in denen Sie ein * .__ verwenden dürfen (z. B. Paging) Warum sollte jede Spalte in der äußeren select-Anweisung angegeben werden, wenn Sie es in der inneren getan haben?
Gibt es eine Möglichkeit, Spalten aus einer Tabelle auszuschließen, ohne .__ anzugeben. alle spalten?
Verwenden Sie deklarative SQL wie üblich, nein.
Ich denke, Ihre vorgeschlagene Syntax ist würdig und gut. Tatsächlich hat die relationale Datenbanksprache 'Tutorial D' eine sehr ähnliche Syntax, bei der auf die Schlüsselwörter ALL BUT
eine Reihe von Attributen (Spalten) folgt.
Der SELECT *
von SQL bekommt jedoch bereits einen großen Flair (die Antwort von @ Guffa hier ist ein typischer Einwand). Ich glaube nicht, dass SELECT ALL BUT
demnächst in den SQL-Standard gelangen wird.
Ich denke, das beste "Umgehen" ist das Erstellen einer VIEW
mit nur den gewünschten Spalten, dann SELECT * FROM ThatView
.
Wenn wir von Prozeduren sprechen, funktioniert es mit diesem Trick, um eine neue Abfrage zu generieren und 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');
Mir ist keine Datenbank bekannt, die dies unterstützt (SQL Server, MySQL, Oracle, PostgreSQL). Es ist definitiv nicht Teil der SQL-Standards, daher müssen Sie nur die gewünschten Spalten angeben.
Sie können natürlich Ihre SQL-Anweisung dynamisch erstellen und vom Server ausführen lassen. Dies eröffnet jedoch die Möglichkeit der SQL-Injection.
Ich weiß, das ist ein bisschen alt, aber ich hatte gerade die gleiche Frage und suchte nach einer Antwort. Dann hatte ich einen leitenden Entwickler, der mir einen sehr einfachen Trick zeigte.
Wenn Sie den Abfrageeditor von Management Studio verwenden, erweitern Sie die Datenbank und dann die Tabelle, aus der Sie auswählen, damit der Spaltenordner angezeigt wird.
Markieren Sie in Ihrer select-Anweisung einfach den Ordner mit den referenzierten Spalten und ziehen Sie ihn in das Abfragefenster. Es fügt alle Spalten der Tabelle ein und entfernt dann einfach die Identitätsspalte aus der Spaltenliste ...
Es ist allgemein üblich, die gewünschten Spalten anzugeben, anstatt nur * anzugeben. Sie sollten also nur angeben, welche Felder Sie auswählen möchten.
Ein Kollege empfahl eine gute Alternative:
Erledigt...
Das hat uns sehr geholfen.
Postgres SQL hat eine Möglichkeit, dies zu tun
pls beziehen sich auf: http://www.postgresonline.com/journal/archives/41-Wie- zum-SELECT-ALL-EXCEPT-some-columns-in-a-table.html
Das Informationsschema 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
Das oben für meine bestimmte Beispieltabelle erzeugte eine SQL-Anweisung, die so aussieht
WÄHLEN Sie o.officepark, o.owner, o.squarefootage VON officepark As o
Um dies zu lösen, verwenden Sie am besten eine Ansicht, in der Sie die erforderlichen Spalten erstellen und Daten daraus abrufen können
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)
Manchmal muss dasselbe Programm unterschiedliche Datenbankstrukturen verarbeiten. Daher konnte ich keine Spaltenliste im Programm verwenden, um Fehler in select
-Anweisungen zu vermeiden.
*
gibt mir alle optionalen Felder. Ich überprüfe vor der Verwendung, ob die Felder in der Datentabelle vorhanden sind. Dies ist mein Grund, *
in select
zu verwenden.
So gehe ich mit ausgeschlossenen Feldern um:
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
Das was ich oft für diesen Fall benutze:
declare @colnames varchar(max)=''
select @[email protected]+','+name from syscolumns where object_id(tablename)=id and name not in (column3,column4)
SET @colnames=RIGHT(@colnames,LEN(@colnames)-1)
@colnames
sieht aus wie column1,column2,column5
Klicken Sie im Objekt-Explorer mit der rechten Maustaste auf die Option "Top 1000-Zeilen auswählen"
Es werden alle Spalten aufgelistet und nicht *. Entfernen Sie dann die unerwünschten Spalten. Sollte viel schneller sein, als selbst zu tippen.
Wenn Sie das Gefühl haben, dass dies ein bisschen zu viel Arbeit ist, rufen Sie die SQL-Eingabeaufforderung von Red Gate ab und geben Sie ssf von tbl ein.
Die vorgeschlagene Antwort (gespeicherte Prozedur) von BartoszX funktionierte für mich nicht, wenn eine Ansicht anstelle einer echten Tabelle verwendet wurde.
Dank für die Idee und den Code unten (außer meinem Fix) gehört BartoszX.
Damit dies sowohl für Tabellen als auch für Ansichten funktioniert, verwenden Sie den folgenden Code:
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
Wäre es nicht einfacher, dies zu tun:
sp_help <table_name>
-Klicken Sie auf die Spalte 'Spaltenname'> Kopieren> Einfügen (erstellt eine vertikale Liste) in ein neues Abfragefenster und geben Sie vor jedem Spaltenwert Kommas ein Schreiben als jeder hier angebotene Code und noch überschaubar.
Ich weiß, dass diese Frage alt ist, aber ich hoffe, dass dies immer noch hilfreich sein kann. Die Antwort ist von einer Diskussion aus SQL Server Forums 1 inspiriert. Sie können dies zu einer gespeicherten Prozedur machen. Es kann auch geändert werden, um außer Feldern mehr als ein Feld hinzuzufügen. Die erste Spalte kann jedoch keine Ausnahme sein.
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
Nachdem ich oben die Lösung gepostet hatte, bekam ich eine bessere Idee:
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
Sie können SQL Complete von devart.com erhalten, das nicht nur die * Wildcard wie bei SQL Prompt von Red Gate (wie in der Antwort von cairnz beschrieben) erweitert, sondern auch ein Drop-Down-Listenfeld mit Kontrollkästchen enthält, in dem Sie alle auswählen können Spalten, die Sie in die Auswahlliste aufnehmen möchten, und diese werden automatisch für Sie eingefügt (und wenn Sie eine Spalte deaktivieren, wird diese automatisch aus der Auswahlliste entfernt).
Dies spart keine Zeit beim Laden aus der Datenbank. Sie können jedoch die Spalte, in der das Array nicht platziert werden soll, immer deaktivieren. Ich hatte mehrere Spalten in einer Tabelle, wollte aber keine bestimmte. Ich war zu faul, sie alle in die SELECT-Anweisung zu schreiben.
$i=0;
$row_array = array();
while($row = mysqli_fetch_assoc($result)){
$row_array[$i]=$row;
unset($row_array[$i]['col_name']);
$i++;
}
Ich habe es so gemacht und es funktioniert gut (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;
Wenn jemand hier MySQL benutzt, wie ich es getan habe:
CREATE TABLE TempTable AS SELECT * FROM #YourTable;
ALTER TABLE TempTable
DROP COLUMN #YourColumn;
SELECT * FROM TempTable;
DROP TABLE TempTable;
Im SSMS geht es mit IntelliSense und Aliasing einfacher. Versuche dies