Alle Spalten außer einer in MySQL auswählen?

365

Ich versuche, eine select-Anweisung zu verwenden, um alle Spalten außer einer aus einer bestimmten MySQL-Tabelle abzurufen. Gibt es eine einfache Möglichkeit, dies zu tun?

BEARBEITEN: Diese Tabelle enthält 53 Spalten (NICHT MEIN DESIGN)

Tom Grochowicz
quelle
6
53 Spalten? Ich würde bei SELECT * bleiben, wie Thomas in diesem Fall vorschlägt ... es sei denn, diese zusätzliche Spalte enthält eine große Datenmenge, deren Abruf unerwünscht wäre ...?
Mike Stone
Außer einer Spalte ... Ich nehme an, Sie wissen, welche ignoriert werden sollte, daher ist INFORMATION_SCHEMA.columns der richtige Weg.
Alfabravo
Schauen Sie sich diese Antwort an, sie macht das, was Sie wollen!
DonL
Die Big-Data-Spalte ist ein echtes Problem, wenn geografische Daten gespeichert werden. Spalten können viele Megabyte groß sein. Sie funktionieren gut in where-Klauseln, um Zeilen zu finden, aber Sie möchten diese Daten oft nicht in den Ergebnissen haben.
Jason
Dies wird häufig verwendet, um die Spalte für die automatische Inkrementierung der ID auszuschließen. Zum Beispiel, um Daten auszuwählen, die in eine andere Tabelle eingefügt werden sollen, die eine eigene ID hat.
ToolmakerSteve

Antworten:

222

Eigentlich gibt es einen Weg, dafür muss man natürlich Berechtigungen haben ...

SET @sql = CONCAT('SELECT ', (SELECT REPLACE(GROUP_CONCAT(COLUMN_NAME), '<columns_to_omit>,', '') FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '<table>' AND TABLE_SCHEMA = '<database>'), ' FROM <table>');

PREPARE stmt1 FROM @sql;
EXECUTE stmt1;

Ersetzen <table>, <database> and <columns_to_omit>

Mahomedalid
quelle
20
Vorbehalt: INFORMATION_SCHEMA-Abfragen weisen eine ziemlich schlechte Leistung auf. Seien Sie also vorsichtig, dass diese Art von Abfrage für nichts im kritischen Pfad enthalten ist.
Bill Karwin
9
Wie @Jan Koritak unten sagte, funktioniert diese Antwort nicht wirklich, wenn die Spalten des Titels, die Sie entfernen möchten, auch eine Unterzeichenfolge des Titels für alle Spalten sind, die Sie behalten möchten. Es gibt eine bessere Antwort, die dieser ähnelt und hier zu finden ist .
DonL
8
Dies ist weitaus schlimmer als nur die Angabe der Spalten, was als bewährte Methode bekannt ist.
HLGEM
3
Dies funktioniert nicht, wenn die Spaltennamen Leerzeichen enthalten. Es sollte aktualisiert werden, um die Namen immer in Backticks zu umgeben<column_name>
AdamF
3
Dies funktioniert auch nicht, wenn die zu ignorierende Spalte die letzte in der Tabellenstruktur aufgeführte ist (da das Ersetzen nicht mit dem nachfolgenden Koma übereinstimmt).
Vincent Pazeller
61

In MySQL-Definitionen (manuell) gibt es so etwas nicht. Wenn Sie jedoch eine wirklich große Anzahl von Spalten haben col1, ..., col100kann Folgendes hilfreich sein:

DROP TABLE IF EXISTS temp_tb;
CREATE TEMPORARY TABLE ENGINE=MEMORY temp_tb SELECT * FROM orig_tb;
ALTER TABLE temp_tb DROP col_x;
SELECT * FROM temp_tb;
Ghionoiu
quelle
4
Hat mir im 3. Schritt eine Fehlermeldung gegeben: "Die Spaltenanzahl stimmt nicht mit der Wertanzahl in Zeile 1 überein". Also habe ich Schritt 2 in "UPDATE temp_tb SET id = NULL" geändert und dann hat es funktioniert.
Oyvey
1
Ok, das funktioniert. Wenn ich diese Abfrage jedoch erneut ausführe, wird der Fehler angezeigt, dass temp_tb bereits vorhanden ist. Wie lange befindet sich temp_tb im Speicher? Entschuldigung, wenn es eine dumme Frage ist. PS hat deine Antwort positiv bewertet.
Karan
2
@ Karan Um diese Abfrage wiederholt auszuführen, fügen Sie am Anfang einen weiteren Befehl hinzu:DROP TABLE IF EXISTS temp_tb;
gregn3
1
@Karan Verwenden Sie den Befehl:, um die Speicher-Engine anzugeben. CREATE TEMPORARY TABLE temp_tb ENGINE=MEMORY (SELECT * FROM orig_tb); Andernfalls wird sie standardmäßig auf der Festplatte gespeichert und überlebt einen Neustart des Servers. ( danke )
gregn3
Hervorragende Antwort. Informationen zum Löschen mehrerer Spalten finden Sie in dieser Antwort .
S3DEV
45

Würde eine Ansicht in diesem Fall besser funktionieren?

CREATE VIEW vwTable
as  
SELECT  
    col1  
    , col2  
    , col3  
    , col..  
    , col53  
FROM table
Brian Childress
quelle
15
HAHA! Ja sicher. Wie konstruieren Sie nun die Ansicht, um alle ABER eine der Spalten einzuschließen? Ich denke, Sie sehen, wie dies die ursprüngliche Frage aufwirft. Tatsächlich habe ich diesen Thread speziell gefunden, weil ich eine Ansicht erstellen wollte, die bestimmte Spalten ausschließt, ohne gezwungen zu sein, alle verbleibenden Spalten explizit in der Ansichtsdefinition aufzulisten.
Chris Nadovich
31

Du kannst tun:

SELECT column1, column2, column4 FROM table WHERE whatever

ohne Spalte3 zu bekommen, obwohl Sie vielleicht nach einer allgemeineren Lösung gesucht haben?

Mike Stone
quelle
3
Die meisten der höher bewerteten Antworten finden meist nur Möglichkeiten, diese exakte Abfrage zu generieren, ohne sie von Hand
einzugeben
5
Aus Wartungsgründen ist es tatsächlich nützlich, eine Abfrage der Art "Alles außer" zu haben. Andernfalls müssen explizite Feldlisten aktualisiert werden, wenn später neue Felder hinzugefügt werden.
Leiavoia
1
@lev, das ist richtig und SIE SOLLTEN !!! Weil Sie nicht wissen, ob Sie zukünftige Spalten haben möchten (dies können Metadatenspalten sein oder solche, die nicht für einen bestimmten Bildschirm gelten). Sie nicht; Ich möchte die Leistung beeinträchtigen, indem Sie mehr zurückgeben, als Sie benötigen (was in 100% der Fälle der Fall ist, wenn Sie einen inneren Join haben). Ich empfehle Ihnen, etwas darüber zu lesen, warum select * ein SQL-Antimuster ist.
HLGEM
26
Das OP gibt an, dass es> 50 Spalten gibt, was ziemlich unpraktisch ist.
August
1
@HLGEM Nicht wirklich, ich wollte alle Spalten auswählen, ohne die Abfrage jedes Mal beizubehalten, wenn ich eine neue Spalte hinzufüge, außer einer von ihnen, und dies würde in meinem Fall nicht einfach funktionieren. Aber trotzdem habe ich Sean O's Lösung für mich selbst
angewendet
26

Wenn Sie den Wert eines Felds ausschließen möchten, z. B. aus Sicherheitsgründen / wegen vertraulicher Informationen, können Sie diese Spalte als null abrufen.

z.B

SELECT *, NULL AS salary FROM users
Sean O.
quelle
13
Warum? Es funktioniert nicht. Wenn Sie ein Spaltengehalt haben, führt diese Abfrage nur zu den Ergebnissen mit zwei Spalten mit dem Namen Gehalt, eine mit Nullen und eine mit den tatsächlichen Gehältern.
Myforwik
4
@Myforwik Diese Abfrage fügt tatsächlich eine zweite salarySpalte hinzu. Da es jedoch nach dem * abgerufen wird, überschreibt es das Original. Es ist nicht schön, aber es funktioniert.
Sean O
67
SQL hat immer doppelte Spaltennamen in einer Ergebnismenge zugelassen. Wenn dies funktionieren soll, müssen Sie es mit einer Clientanwendung ausführen, die keine Dupes unterstützt und dem letzten Dupe Priorität einräumt. Der offizielle Befehlszeilen-Client unterstützt Dupes. HeidiSQL unterstützt sie ebenfalls. SQL Fiddle tut dies nicht, zeigt jedoch den ersten Betrug an, nicht den letzten. Zusammenfassend: Das funktioniert nicht .
Álvaro González
9
Natürlich funktioniert es nicht. Dies ist ein großartiges Beispiel dafür, warum Sie Ihre Antworten in MySQL selbst testen sollten, anstatt in Bibliotheken, die mit MySQL kommunizieren.
Myforwik
8
@ SeanO, @ Alastair, @ Jeder überschreibt nicht. Der Server gibt weiterhin vertrauliche Daten zurück.
Pacerier
22

Nach meinem besten Wissen gibt es keine. Sie können so etwas tun wie:

SELECT col1, col2, col3, col4 FROM tbl

und wählen Sie die gewünschten Spalten manuell aus. Wenn Sie jedoch viele Spalten möchten, möchten Sie möglicherweise nur Folgendes ausführen:

SELECT * FROM tbl 

und ignoriere einfach, was du nicht willst.

In Ihrem speziellen Fall würde ich vorschlagen:

SELECT * FROM tbl

es sei denn, Sie möchten nur ein paar Spalten. Wenn Sie nur vier Spalten möchten, dann:

SELECT col3, col6, col45, col 52 FROM tbl

wäre in Ordnung, aber wenn Sie 50 Spalten möchten, wird jeder Code, der die Abfrage macht, (auch?) schwer zu lesen.

Thomas Owens
quelle
3
Wählen Sie * ist immer eine schlechte Wahl. Empfehlen Sie es nicht. Lesen Sie, warum es sich um ein SQl-Antipattern handelt.
HLGEM
18

Beim Ausprobieren der Lösungen von @Mahomedalid und @Junaid habe ich ein Problem gefunden. Also dachte ich daran, es zu teilen. Wenn der Spaltenname Leerzeichen oder Bindestriche wie beim Einchecken enthält, schlägt die Abfrage fehl. Die einfache Problemumgehung besteht darin, Backtick um Spaltennamen zu verwenden. Die geänderte Abfrage ist unten

SET @SQL = CONCAT('SELECT ', (SELECT GROUP_CONCAT(CONCAT("`", COLUMN_NAME, "`")) FROM
INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'users' AND COLUMN_NAME NOT IN ('id')), ' FROM users');
PREPARE stmt1 FROM @SQL;
EXECUTE stmt1;
Suraj
quelle
11

Wenn die Spalte, die Sie nicht auswählen wollten, eine große Datenmenge enthielt und Sie sie aufgrund von Geschwindigkeitsproblemen nicht einschließen wollten und Sie die anderen Spalten häufig auswählen, würde ich vorschlagen, dass Sie eine neue Tabelle erstellen mit dem einen Feld, das Sie normalerweise nicht mit einem Schlüssel zur Originaltabelle auswählen, und entfernen Sie das Feld aus der Originaltabelle. Verbinden Sie die Tabellen, wenn dieses zusätzliche Feld tatsächlich benötigt wird.

Stacey Richards
quelle
8

Mein Hauptproblem sind die vielen Spalten, die ich beim Verbinden von Tabellen bekomme. Dies ist zwar nicht die Antwort auf Ihre Frage (wie man alle außer bestimmten Spalten aus einer Tabelle auswählt ), aber ich denke, es ist erwähnenswert, dass Sie angeben können, dass alle Spalten aus einer bestimmten Tabelle abgerufen werden sollen, anstatt nur anzugebentable. .

Hier ist ein Beispiel, wie dies sehr nützlich sein kann:

Benutzer auswählen. *, phone.meta_value als Telefon, postleitzahl.meta_value als Postleitzahl

von Benutzern

left join user_meta als Telefon
on ((users.user_id = phone.user_id) AND (phone.meta_key = 'phone'))

left join user_meta als Postleitzahl
on ((users.user_id = zipcode.user_id) AND (zipcode.meta_key = 'postleitzahl'))

Das Ergebnis sind alle Spalten aus der Benutzertabelle und zwei zusätzliche Spalten, die aus der Metatabelle zusammengefügt wurden.

cwd
quelle
2
Vielen Dank, ich muss beim Verbinden alle Spalten der ersten Tabelle und nur ein Feld aus der zweiten Tabelle auswählen, und Ihre Antwort hat mir geholfen.
Mohammed Falahat
5

Ich mochte die Antwort von @Mahomedalidneben dieser Tatsache in Kommentar von informiert @Bill Karwin. Das mögliche Problem, das sich daraus @Jan Koritakergibt, ist wahr, dass ich damit konfrontiert wurde, aber ich habe einen Trick dafür gefunden und möchte ihn hier nur für alle teilen, die mit dem Problem konfrontiert sind.

Wir können die REPLACE-Funktion durch die where-Klausel in der Unterabfrage der Prepared-Anweisung wie folgt ersetzen:

Verwenden Sie meinen Tabellen- und Spaltennamen

SET @SQL = CONCAT('SELECT ', (SELECT GROUP_CONCAT(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'users' AND COLUMN_NAME NOT IN ('id')), ' FROM users');
PREPARE stmt1 FROM @SQL;
EXECUTE stmt1;

Dies schließt also nur das Feld aus id, nicht jedochcompany_id

Junaid
quelle
4

Es wird empfohlen, die Spalten anzugeben, die Sie abfragen, auch wenn Sie alle Spalten abfragen.

Daher würde ich vorschlagen, dass Sie den Namen jeder Spalte in die Anweisung schreiben (mit Ausnahme derjenigen, die Sie nicht möchten).

SELECT
    col1
    , col2
    , col3
    , col..
    , col53

FROM table
mbillard
quelle
Es verhält sich wie ein Vertrag mit dem Code, und wenn Sie sich die Abfrage ansehen, wissen Sie genau, welche Daten Sie daraus extrahieren können, ohne das Schema der Tabelle zu betrachten.
Mbillard
6
@kodecraft: Es ist eine gute Praxis aus dem gleichen Grund, dass es eine gute Praxis ist, immer denselben Typ von einer Funktion zurückzugeben (selbst wenn Sie in einer Sprache arbeiten, in der dies nicht erzwungen wird). Grundsätzlich nur das Prinzip der geringsten Überraschung.
Daniel Pryden
4

Mach einfach

SELECT * FROM table WHERE whatever

Dann lassen Sie die Spalte in Ihrer bevorzugten Programmiersprache fallen: php

while (($data = mysql_fetch_array($result, MYSQL_ASSOC)) !== FALSE) {
   unset($data["id"]);
   foreach ($data as $k => $v) { 
      echo"$v,";
   }      
}
Soth
quelle
6
Es sei denn, die Spalte, die Sie ausschließen möchten, ist ein riesiger BLOB oder so.
Bill Karwin
1
Dies ist schlecht, wenn Sie versuchen, die verschwendeten Daten zu vermeiden.
Kristopher Ives
1 Spalte von 53 sollte keinen Unterschied machen. Wenn ja, ist es wahrscheinlich ein schlechtes Design.
Petr Peller
1
SElect * ist ein SQL-Antimuster und sollte niemals im Produktionscode verwendet werden.
HLGEM
1
Ich bin nicht der Meinung, dass SELECT * eine Art Anti-Pattern ist, das "niemals" im Produktionscode verwendet werden sollte. Es ist weitaus klarer, dass Sie alle Ihre Spalten abgerufen haben - im Vergleich zum Querverweis auf eine lange Liste von Spalten, die tatsächlich alle Felder sein können oder nicht. Es ist auch bei weitem schneller zu codieren. Und es gibt viele, viele Fälle, in denen die Felder der Tabelle genau den Feldern in einer Ansicht oder einem Formular entsprechen.
Geoff Kendall
4

Ich bin mit der "einfachen" Lösung einverstanden, alle Spalten aufzulisten, aber dies kann lästig sein und Tippfehler können viel Zeitverschwendung verursachen. Ich verwende eine Funktion "getTableColumns", um die Namen meiner Spalten abzurufen, die zum Einfügen in eine Abfrage geeignet sind. Dann muss ich nur noch die löschen, die ich nicht will.

CREATE FUNCTION `getTableColumns`(tablename varchar(100)) 
          RETURNS varchar(5000) CHARSET latin1
BEGIN
  DECLARE done INT DEFAULT 0;
  DECLARE res  VARCHAR(5000) DEFAULT "";

  DECLARE col  VARCHAR(200);
  DECLARE cur1 CURSOR FOR 
    select COLUMN_NAME from information_schema.columns 
    where TABLE_NAME=@table AND TABLE_SCHEMA="yourdatabase" ORDER BY ORDINAL_POSITION;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
  OPEN cur1;
  REPEAT
       FETCH cur1 INTO col;
       IF NOT done THEN 
          set res = CONCAT(res,IF(LENGTH(res)>0,",",""),col);
       END IF;
    UNTIL done END REPEAT;
  CLOSE cur1;
  RETURN res;

Ihr Ergebnis gibt eine durch Kommas getrennte Zeichenfolge zurück, zum Beispiel ...

col1, col2, col3, col4, ... col53

David Poor
quelle
4

Ja, obwohl es je nach Tabelle hohe E / A-Werte geben kann, habe ich hier eine Problemumgehung gefunden.

SELECT *
INTO #temp
FROM table

ALTER TABLE #temp DROP COlUMN column_name

SELECT *
FROM #temp
Nathan A.
quelle
Dies ist für jeden mittelgroßen Tisch furchtbar langsam.
Joel
3

Ich bin damit einverstanden, dass es nicht ausreicht Select *, wenn dieser, den Sie nicht benötigen, wie an anderer Stelle erwähnt, ein BLOB ist, möchten Sie nicht, dass sich dieser Overhead einschleicht.

Ich würde eine Ansicht mit den erforderlichen Daten erstellen , dann können Sie Select *bequem - wenn die Datenbanksoftware sie unterstützt. Andernfalls legen Sie die riesigen Daten in eine andere Tabelle.

Nlucaroni
quelle
3

Zuerst dachte ich, Sie könnten reguläre Ausdrücke verwenden, aber da ich die MYSQL-Dokumente gelesen habe, scheint es, dass Sie das nicht können. Wenn ich Sie wäre, würde ich eine andere Sprache (wie PHP) verwenden, um eine Liste der Spalten zu generieren, die Sie abrufen möchten, sie als Zeichenfolge speichern und diese dann zum Generieren von SQL verwenden.

icco
quelle
3

Ich wollte das auch, also habe ich stattdessen eine Funktion erstellt.

public function getColsExcept($table,$remove){
    $res =mysql_query("SHOW COLUMNS FROM $table");

    while($arr = mysql_fetch_assoc($res)){
        $cols[] = $arr['Field'];
    }
    if(is_array($remove)){
        $newCols = array_diff($cols,$remove);
        return "`".implode("`,`",$newCols)."`";
    }else{
        $length = count($cols);
        for($i=0;$i<$length;$i++){
            if($cols[$i] == $remove)
                unset($cols[$i]);
        }
        return "`".implode("`,`",$cols)."`";
    }
}

So funktioniert es, wenn Sie die Tabelle eingeben, dann eine Spalte, die Sie nicht möchten, oder wie in einem Array: array ("id", "name", "Whatevercolumn")

In select können Sie es also folgendermaßen verwenden:

mysql_query("SELECT ".$db->getColsExcept('table',array('id','bigtextcolumn'))." FROM table");

oder

mysql_query("SELECT ".$db->getColsExcept('table','bigtextcolumn')." FROM table");
Kilise
quelle
3

Ich stimme der Antwort von @ Mahomedalid zu, aber ich wollte nicht so etwas wie eine vorbereitete Aussage machen und ich wollte nicht alle Felder eingeben, also hatte ich eine dumme Lösung.

Gehen Sie zu der Tabelle in phpmyadmin-> sql-> select, es wird die Abfrage ausgegeben: kopieren, ersetzen und fertig! :) :)

neelabh
quelle
2

Obwohl ich der Antwort von Thomas (+1;)) zustimme, möchte ich den Vorbehalt hinzufügen, dass die Spalte, die Sie nicht möchten, kaum Daten enthält. Wenn es enorme Mengen an Text, XML oder binären Blobs enthält, nehmen Sie sich Zeit, um jede Spalte einzeln auszuwählen. Ihre Leistung wird sonst leiden. Prost!

ABl.
quelle
2

Die Antwort von Mahomedalid hat ein kleines Problem:

Der Funktionscode für das Ersetzen wurde ersetzt. "<columns_to_delete>, " durch "" ersetzt. Diese Ersetzung hat ein Problem, wenn das zu ersetzende Feld das letzte in der Concat-Zeichenfolge ist, da das letzte Feld kein Komma "" enthält und nicht entfernt wird die Saite.

Mein Vorschlag:

SET @sql = CONCAT('SELECT ', (SELECT REPLACE(GROUP_CONCAT(COLUMN_NAME),
                  '<columns_to_delete>', '\'FIELD_REMOVED\'')
           FROM INFORMATION_SCHEMA.COLUMNS
           WHERE TABLE_NAME = '<table>'
             AND TABLE_SCHEMA = '<database>'), ' FROM <table>');

Ersetzen <table>,<database> und `

Die entfernte Spalte wird durch die Zeichenfolge "FIELD_REMOVED" ersetzt. In meinem Fall funktioniert dies, weil ich versucht habe, den Speicher zu sichern. (Das Feld, das ich entfernt habe, ist ein BLOB von ungefähr 1 MB)

neurotico79
quelle
2

Basierend auf der Antwort von @Mahomedalid habe ich einige Verbesserungen vorgenommen, um "Alle Spalten außer einigen in MySQL auswählen" zu unterstützen.

SET @database    = 'database_name';
SET @tablename   = 'table_name';
SET @cols2delete = 'col1,col2,col3';

SET @sql = CONCAT(
'SELECT ', 
(
    SELECT GROUP_CONCAT( IF(FIND_IN_SET(COLUMN_NAME, @cols2delete), NULL, COLUMN_NAME ) )
    FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tablename AND TABLE_SCHEMA = @database
), 
' FROM ',
@tablename);

SELECT @sql;

Wenn Sie viele Spalten haben, verwenden Sie diese SQL, um group_concat_max_len zu ändern

SET @@group_concat_max_len = 2048;
hahakubile
quelle
2

Vielleicht habe ich eine Lösung für Jan Koritaks aufgezeigte Diskrepanz

SELECT CONCAT('SELECT ',
( SELECT GROUP_CONCAT(t.col)
FROM
(
    SELECT CASE
    WHEN COLUMN_NAME = 'eid' THEN NULL
    ELSE COLUMN_NAME
    END AS col 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_NAME = 'employee' AND TABLE_SCHEMA = 'test'
) t
WHERE t.col IS NOT NULL) ,
' FROM employee' );

Tabelle :

SELECT table_name,column_name 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = 'employee' AND TABLE_SCHEMA = 'test'

===============================

table_name  column_name
employee    eid
employee    name_eid
employee    sal

===============================

Abfrageergebnis:

'SELECT name_eid,sal FROM employee'
Bhavik Shah
quelle
1

Wenn es sich immer um dieselbe Spalte handelt, können Sie eine Ansicht erstellen, in der sie nicht enthalten ist.

Ansonsten nein, ich glaube nicht.

Gareth Simpson
quelle
1

Sie können SQL verwenden, um SQL zu generieren, wenn Sie das erzeugte SQL mögen und auswerten. Dies ist eine allgemeine Lösung, da die Spaltennamen aus dem Informationsschema extrahiert werden. Hier ist ein Beispiel aus der Unix-Befehlszeile.

Ersetzen

  • MYSQL mit Ihrem MySQL-Befehl
  • TABELLE mit dem Tabellennamen
  • EXCLUDEDFIELD mit ausgeschlossenem Feldnamen
echo $(echo 'select concat("select ", group_concat(column_name) , " from TABLE") from information_schema.columns where table_name="TABLE" and column_name != "EXCLUDEDFIELD" group by "t"' | MYSQL | tail -n 1) | MYSQL

Sie müssen die Spaltennamen auf diese Weise nur einmal extrahieren, um die Spaltenliste ohne diese Spalte zu erstellen, und dann einfach die von Ihnen erstellte Abfrage verwenden.

Also so etwas wie:

column_list=$(echo 'select group_concat(column_name) from information_schema.columns where table_name="TABLE" and column_name != "EXCLUDEDFIELD" group by "t"' | MYSQL | tail -n 1)

Jetzt können Sie die $column_listZeichenfolge in von Ihnen erstellten Abfragen wiederverwenden .

rplevy
quelle
1

Ich möchte einen weiteren Gesichtspunkt hinzufügen, um dieses Problem zu lösen, insbesondere wenn Sie eine kleine Anzahl von Spalten entfernen müssen.

Sie können ein DB-Tool wie MySQL Workbench verwenden, um die select-Anweisung für Sie zu generieren. Sie müssen diese Spalten für die generierte Anweisung nur manuell entfernen und in Ihr SQL-Skript kopieren.

In MySQL Workbench können Sie Folgendes generieren:

Klicken Sie mit der rechten Maustaste auf die Tabelle -> An SQL-Editor senden -> Alle Anweisungen auswählen.

H. Paúl Cervera García
quelle
1

Die akzeptierte Antwort weist mehrere Mängel auf.

  • Es schlägt fehl, wenn für die Tabellen- oder Spaltennamen Backticks erforderlich sind
  • Es schlägt fehl, wenn die Spalte, die Sie weglassen möchten, die letzte in der Liste ist
  • Der Tabellenname muss zweimal aufgelistet werden (einmal für die Auswahl und einmal für den Abfragetext), was redundant und unnötig ist
  • Es kann möglicherweise Spaltennamen in der falschen Reihenfolge zurückgeben

All diese Probleme können überwunden werden, indem Sie einfach Backticks in das SEPARATORfür Sie einfügen GROUP_CONCATund stattdessen eine WHEREBedingung verwenden REPLACE(). Für meine Zwecke (und ich stelle mir viele andere vor) wollte ich, dass die Spaltennamen in derselben Reihenfolge zurückgegeben werden, in der sie in der Tabelle selbst erscheinen. Um dies zu erreichen, verwenden wir hier eine explizite ORDER BYKlausel innerhalb der GROUP_CONCAT()Funktion:

SELECT CONCAT(
    'SELECT `',
    GROUP_CONCAT(COLUMN_NAME ORDER BY `ORDINAL_POSITION` SEPARATOR '`,`'),
    '` FROM `',
    `TABLE_SCHEMA`,
    '`.`',
    TABLE_NAME,
    '`;'
)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE `TABLE_SCHEMA` = 'my_database'
    AND `TABLE_NAME` = 'my_table'
    AND `COLUMN_NAME` != 'column_to_omit';
Billynoah
quelle
0

Ich habe einen Vorschlag, aber keine Lösung. Wenn einige Ihrer Spalten größere Datensätze enthalten, sollten Sie Folgendes versuchen

SELECT *, LEFT(col1, 0) AS col1, LEFT(col2, 0) as col2 FROM table
MR_AMDEV
quelle
-1

Ich bin ziemlich spät dran, eine Antwort darauf zu finden. Ich habe es immer so gemacht und ehrlich gesagt, es ist 100 Mal besser und ordentlicher als die beste Antwort. Ich hoffe nur, dass jemand es sieht. Und finde es nützlich

    //create an array, we will call it here. 
    $here = array();
    //create an SQL query in order to get all of the column names
    $SQL = "SHOW COLUMNS FROM Table";
        //put all of the column names in the array
        foreach($conn->query($SQL) as $row) {
            $here[] = $row[0];
        }
    //now search through the array containing the column names for the name of the column, in this case i used the common ID field as an example
    $key = array_search('ID', $here);
    //now delete the entry
    unset($here[$key]);
Nick
quelle
Es ist vielleicht ordentlich, aber es beantwortet nicht die Frage: Er hat nicht nach PHP gefragt, und Sie geben keine Select-Anweisung oder ein Ergebnis dessen, was er will, sondern nur ein PHP-Array, das die gewünschten Spalten enthält.
Gou1
2
–1. Dies ist kein SQL-Code, und hier gibt es keine SELECTAussage - das Wort kommt nicht einmal vor.
Frungi
Dies ist nur insofern besser, als (a) Sie mit PHP besser vertraut sind als mit SQL, oder (b) Sie Ihren Code aus Gründen der Lesbarkeit gerne über mehrere Zeilen verteilen. Ich würde Punkt (b) zugeben. Ihr Ansatz wäre auch weniger performant, obwohl der Unterschied in vielen Anwendungsfällen gering wäre. Siehe auch andere Kommentare zu Ihrer Frage. Es lohnt sich nicht, darüber zu schreien. Schlagen Sie daher vor, Ihren unangemessenen Kommentar aus der ursprünglichen Frage zu entfernen.
mc0e
-5

Select * ist ein SQL-Antimuster. Es sollte aus vielen Gründen nicht im Produktionscode verwendet werden, einschließlich:

Die Verarbeitung dauert etwas länger. Wenn Dinge millionenfach ausgeführt werden, können diese winzigen Teile eine Rolle spielen. Eine langsame Datenbank, in der die Langsamkeit durch diese Art von schlampiger Codierung verursacht wird, ist am schwierigsten zu optimieren.

Dies bedeutet, dass Sie wahrscheinlich mehr Daten senden, als Sie benötigen, was sowohl zu Server- als auch zu Netzwerkengpässen führt. Wenn Sie einen inneren Join haben, ist die Wahrscheinlichkeit, dass mehr Daten gesendet werden, als Sie benötigen, 100%.

Dies führt zu Wartungsproblemen, insbesondere wenn Sie neue Spalten hinzugefügt haben, die nicht überall angezeigt werden sollen. Wenn Sie eine neue Spalte haben, müssen Sie möglicherweise etwas an der Schnittstelle tun, um zu bestimmen, was mit dieser Spalte geschehen soll.

Es kann Ansichten unterbrechen (ich weiß, dass dies auf dem SQL-Server zutrifft, es kann auf MySQL zutreffen oder nicht).

Wenn jemand dumm genug ist, die Tabellen mit den Spalten in einer anderen Reihenfolge neu zu erstellen (was Sie nicht tun sollten, aber es passiert immer wieder), können alle Arten von Code beschädigt werden. Insbesondere Code für eine Einfügung, bei der Sie die Stadt plötzlich in das Feld address_3 einfügen, da die Datenbank nur in der Reihenfolge der Spalten ausgeführt werden kann, ohne dies anzugeben. Dies ist schon schlimm genug, wenn sich die Datentypen ändern, aber schlimmer, wenn die ausgetauschten Spalten denselben Datentyp haben, da Sie manchmal schlechte Daten einfügen können, die ein Chaos beim Aufräumen sind. Sie müssen sich um die Datenintegrität kümmern.

Wenn es in einer Einfügung verwendet wird, wird die Einfügung unterbrochen, wenn in einer Tabelle eine neue Spalte hinzugefügt wird, in der anderen jedoch nicht.

Es könnte Auslöser brechen. Auslöserprobleme können schwierig zu diagnostizieren sein.

Addieren Sie all dies gegen die Zeit, die zum Hinzufügen der Spaltennamen erforderlich ist (zum Teufel haben Sie möglicherweise sogar eine Schnittstelle, über die Sie die Spaltennamen ziehen können (ich weiß, dass ich dies in SQL Server tue, ich wette, es gibt eine Möglichkeit dazu) Dies ist ein Tool, mit dem Sie MySQL-Abfragen schreiben.) Mal sehen: "Ich kann Wartungsprobleme verursachen, ich kann Leistungsprobleme verursachen und ich kann Probleme mit der Datenintegrität verursachen, aber hey, ich habe fünf Minuten Entwicklungszeit gespart." in den spezifischen Spalten, die Sie möchten.

Ich schlage außerdem vor, dass Sie dieses Buch lesen: http://www.amazon.com/SQL-Antipatterns-Programming-Pragmatic-Programmers-ebook/dp/B00A376BB2/ref=sr_1_1?s=digital-text&ie=UTF8&qid=1389896688&sr=1- 1 & keywords = sql + antipatterns

HLGEM
quelle