Ich frage mich, ob dies in SQL möglich ist. Angenommen, Sie haben zwei Tabellen A und B, und Sie wählen in Tabelle A aus und verbinden sich in Tabelle B:
SELECT a.*, b.* FROM TABLE_A a JOIN TABLE_B b USING (some_id);
Wenn Tabelle A die Spalten 'a_id', 'name' und 'some_id' enthält und Tabelle B 'b_id', 'name' und 'some_id' enthält, gibt die Abfrage die Spalten 'a_id', 'name', 'some_id' zurück ',' b_id ',' name ',' some_id '. Gibt es eine Möglichkeit, die Spaltennamen von Tabelle B voranzustellen, ohne jede Spalte einzeln aufzulisten? Das Äquivalent dazu:
SELECT a.*, b.b_id as 'b.b_id', b.name as 'b.name', b.some_id as 'b.some_id'
FROM TABLE_A a JOIN TABLE_B b USING (some_id);
Aber wie erwähnt, ohne jede Spalte aufzulisten, so etwas wie:
SELECT a.*, b.* as 'b.*'
FROM TABLE_A a JOIN TABLE_B b USING (some_id);
Grundsätzlich etwas zu sagen: "Stellen Sie jeder von b. * Zurückgegebenen Spalte 'etwas' voran". Ist das möglich oder habe ich kein Glück?
Vielen Dank im Voraus für Ihre Hilfe!
BEARBEITEN: Ratschläge zur Nichtverwendung von SELECT * usw. sind gültige Ratschläge, aber in meinem Kontext nicht relevant. Halten Sie sich daher bitte an das vorliegende Problem. Ist es möglich, allen ein Präfix (eine in der SQL-Abfrage angegebene Konstante) hinzuzufügen? Spaltennamen einer Tabelle in einem Join?
BEARBEITEN: Mein letztendliches Ziel ist es, ein SELECT * für zwei Tabellen mit einem Join durchzuführen und anhand der Namen der Spalten in meiner Ergebnismenge zu erkennen, welche Spalten aus Tabelle A stammen und welche Spalten stammen aus Tabelle B. Auch hier möchte ich keine Spalten einzeln auflisten müssen, sondern muss in der Lage sein, SELECT * auszuführen.
Antworten:
Ich sehe hier zwei mögliche Situationen. Zunächst möchten Sie wissen, ob es dafür einen SQL-Standard gibt, den Sie im Allgemeinen unabhängig von der Datenbank verwenden können. Nein, da ist kein. Zweitens möchten Sie wissen, was ein bestimmtes DBMS-Produkt betrifft. Dann müssen Sie es identifizieren. Aber ich stelle mir vor, die wahrscheinlichste Antwort ist, dass Sie so etwas wie "a.id, b.id" zurückbekommen, da Sie auf diese Weise die Spalten in Ihrem SQL-Ausdruck identifizieren müssten. Der einfachste Weg, um herauszufinden, was die Standardeinstellung ist, besteht darin, eine solche Abfrage zu senden und zu sehen, was Sie zurückerhalten. Wenn Sie angeben möchten, welches Präfix vor dem Punkt steht, können Sie beispielsweise "SELECT * FROM a AS my_alias" verwenden.
quelle
Die Antwort auf Ihre Frage scheint Nein zu sein. Sie können jedoch auch eine Dummy-Spalte zuweisen, um jede neue Tabelle zu trennen. Dies funktioniert besonders gut, wenn Sie eine Ergebnismenge für eine Liste von Spalten in einer Skriptsprache wie Python oder PHP durchlaufen.
Mir ist klar, dass dies Ihre Frage nicht genau beantwortet, aber wenn Sie ein Codierer sind, ist dies eine großartige Möglichkeit, Tabellen mit doppelten Spaltennamen zu trennen. Hoffe das hilft jemandem.
quelle
Ich verstehe vollkommen, warum dies notwendig ist - zumindest für mich ist es beim Rapid Prototyping praktisch, wenn viele Tabellen verbunden werden müssen, einschließlich vieler innerer Verknüpfungen. Sobald ein Spaltenname in einem zweiten Platzhalter für "jointable. *" -Feld identisch ist, werden die Feldwerte der Haupttabelle mit den Werten für jointable überschrieben. Fehleranfällig, frustrierend und eine Verletzung von DRY, wenn die Tabellenfelder immer wieder manuell mit Aliasnamen angegeben werden müssen ...
Hier ist eine PHP-Funktion (Wordpress), um dies durch Codegenerierung zu erreichen, zusammen mit einem Beispiel für deren Verwendung. In diesem Beispiel wird es verwendet, um schnell eine benutzerdefinierte Abfrage zu generieren, die die Felder eines verwandten WordPress-Beitrags bereitstellt, auf den über ein erweitertes Feld für benutzerdefinierte Felder verwiesen wurde .
Die Ausgabe:
quelle
Die einzige mir bekannte Datenbank, die dies tut, ist SQLite, abhängig von den Einstellungen, die Sie mit
PRAGMA full_column_names
und konfigurierenPRAGMA short_column_names
. Siehe http://www.sqlite.org/pragma.htmlAnsonsten kann ich nur empfehlen, Spalten in einer Ergebnismenge nach Ordnungsposition und nicht nach Spaltennamen abzurufen, wenn Sie zu viel Mühe haben, die Namen der Spalten in Ihre Abfrage einzugeben.
Dies ist ein gutes Beispiel dafür, warum es eine schlechte Praxis ist, sie zu verwenden,
SELECT *
da Sie schließlich ohnehin alle Spaltennamen eingeben müssen.Ich verstehe die Notwendigkeit, Spalten zu unterstützen, deren Name oder Position sich ändern kann, aber die Verwendung von Platzhaltern macht dies schwieriger und nicht einfacher.
quelle
full_column_names
und in SQLite veraltetshort_column_names
sind .Ich bin in der Art des gleichen Bootes wie OP - ich habe Dutzende von Feldern aus 3 verschiedenen Tabellen, denen ich beitrete, von denen einige den gleichen Namen haben (dh ID, Name usw.). Ich möchte nicht jedes Feld auflisten, daher bestand meine Lösung darin, die Felder mit einem gemeinsamen Namen zu aliasen und select * für diejenigen zu verwenden, die einen eindeutigen Namen haben.
Zum Beispiel :
Tabelle a: ID, Name, Feld1, Feld2 ...
Tabelle b: ID, Name, Feld3, Feld4 ...
Wählen Sie a.id als aID, a.name als aName, a. *, b.id als bID, b.name als bName, b. * .....
Beim Zugriff auf die Ergebnisse habe ich die Aliasnamen für diese Felder und ignoriere die "ursprünglichen" Namen.
Vielleicht nicht die beste Lösung, aber es funktioniert für mich ... ich benutze MySQL
quelle
Verschiedene Datenbankprodukte geben Ihnen unterschiedliche Antworten. Aber Sie bereiten sich auf Verletzungen vor, wenn Sie dies sehr weit tragen. Sie sind weitaus besser dran, die gewünschten Spalten auszuwählen und ihnen Ihre eigenen Aliase zu geben, damit die Identität jeder Spalte kristallklar ist und Sie sie in den Ergebnissen unterscheiden können.
quelle
Diese Frage ist in der Praxis sehr nützlich. Es ist nur erforderlich, alle expliziten Spalten in der Softwareprogrammierung aufzulisten, wobei Sie besonders darauf achten, mit allen Bedingungen umzugehen.
Stellen Sie sich vor, wir müssen beim Debuggen oder beim Versuch, DBMS als tägliches Office-Tool zu verwenden, anstelle einer veränderbaren Implementierung der abstrakten zugrunde liegenden Infrastruktur eines bestimmten Programmierers viele SQLs codieren. Das Szenario ist überall zu finden, z. B. bei der Datenbankkonvertierung, Migration, Verwaltung usw. Die meisten dieser SQLs werden nur einmal ausgeführt und nie wieder verwendet. Geben Sie an, dass jeder Spaltenname nur Zeitverschwendung ist. Und vergessen Sie nicht, dass die Erfindung von SQL nicht nur für Programmierer gedacht ist.
Normalerweise erstelle ich eine Dienstprogrammansicht mit vorangestellten Spaltennamen. Hier ist die Funktion in pl / pgsql. Es ist nicht einfach, aber Sie können sie in andere Prozedursprachen konvertieren.
Beispiele:
quelle
Ich verstehe Ihr Problem mit doppelten Feldnamen vollkommen.
Ich brauchte das auch, bis ich meine eigene Funktion codierte, um es zu lösen. Wenn Sie PHP verwenden, können Sie es verwenden oder Ihre in der Sprache codieren, für die Sie sie verwenden, wenn Sie über die folgenden Funktionen verfügen.
Der Trick dabei ist, dass
mysql_field_table()
der Tabellenname undmysql_field_name()
das Feld für jede Zeile im Ergebnis zurückgegeben werden, wenn es mit kommtmysql_num_fields()
sodass Sie sie in einem neuen Array mischen können.Dies stellt alle Spalten voran;)
Grüße,
quelle
Hierfür gibt es keinen SQL-Standard.
Mit der Codegenerierung (entweder bei Bedarf beim Erstellen oder Ändern der Tabellen oder zur Laufzeit) können Sie dies jedoch ganz einfach tun:
quelle
Ich kann mir zwei Möglichkeiten vorstellen, um dies auf wiederverwendbare Weise zu erreichen. Eine besteht darin, alle Ihre Spalten mit einem Präfix für die Tabelle umzubenennen, aus der sie stammen. Ich habe das schon oft gesehen, aber ich mag es wirklich nicht. Ich finde, dass es redundant ist, viel Tipparbeit verursacht und Sie immer Aliase verwenden können, wenn Sie den Fall eines Spaltennamens mit unklarem Ursprung abdecken müssen.
Die andere Möglichkeit, die ich Ihnen in Ihrer Situation empfehlen würde, wenn Sie dies durchschauen möchten, besteht darin, Ansichten für jede Tabelle zu erstellen, die den Alias der Tabellennamen enthält. Dann verbinden Sie sich mit diesen Ansichten und nicht mit den Tabellen. Auf diese Weise können Sie * verwenden, wenn Sie möchten, und die ursprünglichen Tabellen mit den ursprünglichen Spaltennamen verwenden, wenn Sie möchten. Außerdem können Sie nachfolgende Abfragen einfacher schreiben, da Sie die Umbenennungsarbeiten in den Ansichten bereits durchgeführt haben.
Schließlich ist mir nicht klar, warum Sie wissen müssen, aus welcher Tabelle die einzelnen Spalten stammen. Ist das wichtig? Letztendlich kommt es auf die Daten an, die sie enthalten. Ob UserID aus der User-Tabelle oder der UserQuestion-Tabelle stammt, spielt keine Rolle. Es ist natürlich wichtig, wann Sie es aktualisieren müssen, aber zu diesem Zeitpunkt sollten Sie Ihr Schema bereits gut genug kennen, um dies festzustellen.
quelle
Sie können auch Red Gate SQL Refactor oder SQL Prompt verwenden, mit denen Sie SELECT * mit einem Klick auf die Tabulatortaste in Spaltenlisten erweitern können
Wenn Sie also in Ihrem Fall SELECT * FROM A JOIN B eingeben ... Gehen Sie zum Ende von *, Tab-Taste, voila! Sie sehen SELECT A.column1, A.column2, ...., B.column1, B.column2 FROM A JOIN B.
Es ist jedoch nicht kostenlos
quelle
Kann dies nicht ohne Aliasing tun, einfach weil, wie werden Sie auf ein Feld in der where-Klausel verweisen, wenn dieses Feld in den 2 oder 3 Tabellen vorhanden ist, denen Sie beitreten? Es wird für MySQL unklar sein, auf welche Sie sich beziehen möchten.
quelle
Ich habe ein ähnliches Problem gelöst, indem ich die Felder in den beteiligten Tabellen umbenannt habe. Ja, ich hatte das Privileg, dies zu tun und zu verstehen, dass es möglicherweise nicht jeder hat. Ich habe jedem Feld in einer Tabelle, die den Tabellennamen darstellt, ein Präfix hinzugefügt. Somit würde die von OP gepostete SQL unverändert bleiben -
und trotzdem die erwarteten Ergebnisse liefern - einfache Identifizierung, zu welcher Tabelle die Ausgabefelder gehören.
quelle
select * führt normalerweise zu schlechtem Code, da neue Spalten häufig hinzugefügt werden oder die Reihenfolge der Spalten in Tabellen häufig geändert wird, wodurch select * normalerweise auf sehr subtile Weise unterbrochen wird. Das Auflisten von Spalten ist also die richtige Lösung.
Sie sind sich nicht sicher über MySQL, aber in SQL Server können Sie Spaltennamen aus Syscolumns auswählen und die select-Klausel dynamisch erstellen.
quelle
Wenn Sie Bedenken hinsichtlich Schemaänderungen haben, funktioniert dies möglicherweise für Sie: 1. Führen Sie für alle beteiligten Tabellen eine Abfrage 'DESCRIBE table' aus. 2. Verwenden Sie die zurückgegebenen Feldnamen, um dynamisch eine Zeichenfolge von Spaltennamen zu erstellen, denen der ausgewählte Alias vorangestellt ist.
quelle
Für diejenigen, die die MySQL C-API verwenden, gibt es eine direkte Antwort auf Ihre Frage.
Angesichts der SQL:
Die Ergebnisse von 'mysql_stmt_result_metadata ()' geben die Definition Ihrer Felder aus Ihrer vorbereiteten SQL-Abfrage in die Struktur MYSQL_FIELD []. Jedes Feld enthält die folgenden Daten:
Beachten Sie die Felder: Katalog, Tabelle, Organisationsname
Sie wissen jetzt, welche Felder in Ihrem SQL zu welchem Schema (auch bekannt als Katalog) und Tabelle gehören. Dies reicht aus, um jedes Feld generisch aus einer SQL-Abfrage mit mehreren Tabellen zu identifizieren, ohne dass ein Alias erstellt werden muss.
Es wird gezeigt, dass ein tatsächliches Produkt, SqlYOG, genau diese Daten in einem solchen Manor verwendet, dass es in der Lage ist, jede Tabelle eines Joins mit mehreren Tabellen unabhängig zu aktualisieren, wenn die PK-Felder vorhanden sind.
quelle
Aus dieser Lösung heraus würde ich das Problem folgendermaßen angehen:
Erstellen Sie zunächst eine Liste aller
AS
Anweisungen:Verwenden Sie es dann in Ihrer Abfrage:
Dies muss jedoch möglicherweise geändert werden, da etwas Ähnliches nur in SQL Server getestet wird. Dieser Code funktioniert jedoch nicht genau in SQL Server, da USING nicht unterstützt wird.
Bitte kommentieren Sie, ob Sie diesen Code zB für MySQL testen / korrigieren können.
quelle
Kürzlich ist dieses Problem in NodeJS und Postgres aufgetreten.
ES6-Ansatz
Da mir keine RDBMS-Funktionen bekannt sind, die diese Funktionalität bieten, habe ich ein Objekt erstellt, das alle meine Felder enthält, z.
Definierte einen Reduzierer, um die Zeichenfolgen zusammen mit einem Tabellennamen zu verketten:
Dies gibt ein Array von Zeichenfolgen zurück. Nennen Sie es für jede Tabelle und kombinieren Sie die Ergebnisse:
Geben Sie die endgültige SQL-Anweisung aus:
quelle
Ich habe eine Lösung implementiert, die auf der Antwort basiert, die die Verwendung von Dummy- oder Sentinel-Spalten im Knoten vorschlägt . Sie würden es verwenden, indem Sie SQL wie folgt generieren:
Und dann die Zeile nachbearbeiten, die Sie von Ihrem Datenbanktreiber erhalten, wie
addPrefixes(row)
.Die Umsetzung (bezogen auf das
fields
/rows
zurückgekehrt von meinem Fahrer, sondern sollte einfach sein , für andere DB - Treiber zu ändern):Prüfung:
quelle
Ich verwende Excel, um die Prozedur zu verketten. Zum Beispiel wähle ich zuerst * aus und erhalte alle Spalten, füge sie in Excel ein. Schreiben Sie dann den Code auf, den ich zum Umgeben der Spalte benötige. Angenommen, ich musste eine Reihe von Spalten anzeigen. Ich hätte meine Felder in der Spalte a und "as prev_" in Spalte B und meine Felder wieder in Spalte c. In Spalte d hätte ich eine Spalte.
Verwenden Sie dann concatanate in Spalte e und führen Sie sie zusammen, wobei Sie darauf achten, Leerzeichen einzuschließen. Dann schneiden Sie dies aus und fügen Sie es in Ihren SQL-Code ein. Ich habe diese Methode auch verwendet, um case-Anweisungen für dasselbe Feld und andere längere Codes zu erstellen, die ich für jedes Feld in einer Tabelle mit mehreren hundert Feldern ausführen muss.
quelle
In postgres verwende ich die json-Funktionen, um stattdessen json-Objekte zurückzugeben. Nach der Abfrage codiere ich die Felder mit dem Suffix _json.
IE:
Dann durchlaufe ich in PHP (oder einer anderen Sprache) die zurückgegebenen Spalten und json_decode (), wenn sie das Suffix "_json" haben (wobei auch das Suffix entfernt wird. Am Ende erhalte ich ein Objekt namens "tab1", das alle enthält tab1-Felder und ein anderes mit dem Namen "tab2", das alle tab2-Felder enthält.
quelle
PHP 7.2 + MySQL / Mariadb
MySQL sendet Ihnen mehrere Felder mit demselben Namen. Auch im Terminal-Client. Wenn Sie jedoch ein assoziatives Array möchten, müssen Sie die Schlüssel selbst erstellen.
Danke an @axelbrz für das Original. Ich habe es auf neueres PHP portiert und ein wenig aufgeräumt:
quelle