Wie werden mehrdeutige Spaltennamen beim Abrufen von Ergebnissen aufgelöst?

Lesezeit: 6 Minuten

Wie werden mehrdeutige Spaltennamen beim Abrufen von Ergebnissen aufgelost
Dan Burzo

Ich habe zwei Tabellen in meiner Datenbank:

NEWS-Tabelle mit Spalten:

  • id – die Nachrichten-ID
  • user – die Benutzer-ID des Autors)

USERS-Tabelle mit Spalten:

  • id – die Benutzer-ID

Ich möchte dieses SQL ausführen:

SELECT * FROM news JOIN users ON news.user = user.id 

Wenn ich die Ergebnisse in PHP erhalte, möchte ich ein assoziatives Array erhalten und Spaltennamen erhalten $row['column-name']. Wie erhalte ich die Nachrichten-ID und die Benutzer-ID mit demselben Spaltennamen?

Sie können Aliasse für die ausgewählten Spalten festlegen:

$query = 'SELECT news.id AS newsId, user.id AS userId, [OTHER FIELDS HERE] FROM news JOIN users ON news.user = user.id'

  • Diese Antwort hat die Antworten auf stackoverflow.com/questions/9233387/sql-should-i-use-a-join für mich zum Laufen gebracht, danke!

    – AVProgrammierer

    10. Februar 2012 um 22:24 Uhr

  • Der Hauptnachteil dieses Ansatzes ist, dass anders SELECT *, ist die Abfrage eng an die Tabellenstruktur gekoppelt. Das heißt, wann immer Sie Spalten im Schema hinzufügen/löschen/umbenennen, müssen Sie Ihre Abfrage entsprechend ändern.

    – Ron Inbar

    12. Juni 2014 um 16:11 Uhr


  • @RonInbar. SELECT * ist ein Wartungsalptraum in großen Systemen. Sie schlagen vor, dass das Hinzufügen einer Spalte einfach ist und bei Verwendung keine Änderung an SQL erfordert SELECT *, dies ist jedoch nicht der Fall wie bei dem hier identifizierten Aliasing-Problem. Es kann auch eine unnötige Auswirkung auf die Leistung haben, wenn das neue Feld groß ist. Es kann auch clientseitige Kontrollen unterbrechen, die eine bestimmte Zahl oder Felder erwarten. Ich kann weitermachen, aber die Vorteile von SELECT * verschwinden sehr schnell, wenn Sie die Auswirkungen verstehen, die sie auf Wartbarkeit und Leistung haben.

    – simo.3792

    28. Oktober 2014 um 23:51 Uhr

  • @ simo.379209 Ich würde eher sagen, dass select * ein Albtraum sein kann. Es war in unserem letzten. In unserem aktuellen System ist alles von Grund auf so aufgebaut, dass erweiterbare Datenstrukturen verwendet werden. Prüfungen haben die Form „sind diese Daten vorhanden“ und nicht „sind diese Daten und nicht mehr vorhanden“. Wir sind dabei, einen Chaos-Affen einzubauen, der die Spaltenreihenfolge randomisiert und neue Spalten hinzufügt. Wir haben viele Vorteile daraus gezogen, dass wir Funktionen schneller und mit weniger Brüchen entwickeln konnten. Ob select * schlecht ist, hängt ganz vom Kontext ab, selbst in sehr großen Systemen.

    – Max Murphy

    21. Juli 2016 um 13:18 Uhr

  • Es scheint, als ob es eine Option geben sollte, bei der Sie select table.id es sollte die Spalte zurückgeben table.id. Scheint eine einfache Funktion zu sein, die Aliasing verhindern würde. In PHP wird es ein bisschen mühsam sein, die select-Anweisung mit einem Alias ​​zu versehen.

    – Kellen Stuart

    6. September 2016 um 18:53 Uhr

Sie können entweder die numerischen Indizes ($row[0]) oder besser verwenden AS im MySQL:

SELECT *, user.id AS user_id FROM ...

  • Beachten Sie auch, dass, wenn Sie wildwarcd verwenden *, muss es das erste in der select-Klausel sein. NICHT: SELECT user_id,* ...

    – Anders

    30. September 2011 um 11:38 Uhr

  • Stimmt, aber man kann es immer tun SELECT user.id AS user_id, user.* FROM ... wenn die Reihenfolge wichtig ist.

    – Kyrill

    6. Februar 2016 um 17:51 Uhr

1647948249 39 Wie werden mehrdeutige Spaltennamen beim Abrufen von Ergebnissen aufgelost
Eab

Ich habe das gerade herausgefunden. Es ist wahrscheinlich eine schlechte Praxis, aber in diesem Fall hat es für mich funktioniert.

Ich bin einer der faulen Menschen, die nicht jeden Spaltennamen mit einem Tabellenpräfix aliasieren oder ausschreiben möchten.

Mit können Sie alle Spalten einer bestimmten Tabelle auswählen table_name.* in Ihrer ausgewählten Aussage.

Wenn Sie Spaltennamen dupliziert haben, überschreibt mysql vom ersten bis zum letzten. Die Daten aus dem ersten duplizierten Spaltennamen werden überschrieben, wenn dieser Spaltenname erneut gefunden wird. Der doppelte Spaltenname, der zuletzt kommt, gewinnt also.

Wenn ich 3 Tabellen verbinde, die jeweils einen doppelten Spaltennamen enthalten, bestimmt die Reihenfolge der Tabellen in der Select-Anweisung, welche Daten ich für die doppelte Spalte erhalte.

Beispiel:

SELECT table1.* , table2.* , table3.* FROM table1 LEFT JOIN table2 ON table1.dup = table2.dup LEFT JOIN table3 ON table2.dup = table3.dup;

Im obigen Beispiel ist der Wert von dup Ich bekomme wird sein von table3.

Was, wenn ich will dup der Wert von sein table1?

Dann muss ich das machen:

SELECT table3.* , table2.* , table1.* FROM table1 LEFT JOIN table2 ON table1.dup = table2.dup LEFT JOIN table3 ON table2.dup = table3.dup;

Jetzt, table1 kommt zuletzt, also der Wert von dup wird der Wert aus Tabelle1 sein.

Ich habe den Wert bekommen, den ich wollte dup ohne jede einzelne verdammte Spalte schreiben zu müssen, und ich bekomme immer noch alle Spalten, mit denen ich arbeiten kann. Yay!

Ich kenne den Wert von dup sollte in allen 3 Tabellen gleich sein, aber was wäre wenn table3 hat keinen übereinstimmenden Wert für dup? Dann dup wäre im ersten Beispiel leer, und das wäre schade.

  • Sich auf eine undokumentierte Bestellung zu verlassen, die jetzt für Sie funktioniert und keine Fehler verursacht, wenn sich die Datenbankimplementierung ändert, ist eine SCHRECKLICHE Idee.

    – simo.3792

    28. Oktober 2014 um 23:36 Uhr

  • Der Bestell-Hack ist beängstigend, aber +1, um mit auswählen zu können table.* damit ich das kann SELECT table1.*, table2.this_one_column_need FROM table1 INNER JOIN table2 ON....

    – tobek

    4. Februar 2016 um 9:35 Uhr

@ Jason. Sie haben Recht, außer dass PHP der Übeltäter ist und nicht MySQL. Wenn Sie Ihre setzen JOIN In Mysql Workbench erhalten Sie drei Spalten mit genau demselben Namen (eine für jede Tabelle), aber nicht mit denselben Daten (einige werden null wenn diese Tabelle keine Übereinstimmung für die hat JOIN).

In PHP, wenn Sie verwenden MYSQL_NUM in mysql_fetch_array() dann bekommst du alle spalten. Das Problem ist, wenn Sie verwenden mysql_fetch_array() mit MYSQL_ASSOC. Dann baut PHP innerhalb dieser Funktion den Rückgabewert wie folgt auf:

$row['dup'] = [value from table1]

und später…

$row['dup'] = [value from table2]

$row['dup'] = [value from table3]

Sie erhalten also nur den Wert von table3. Das Problem ist, dass eine Ergebnismenge von MySQL Spalten mit demselben Namen enthalten kann, aber assoziative Arrays in PHP erlauben keine doppelten Schlüssel in Arrays. Wenn die Daten in assoziativen Arrays gespeichert werden, gehen in PHP einige Informationen stillschweigend verloren …

Noch ein Tipp: Wenn Sie saubereren PHP-Code haben möchten, können Sie eine Ansicht in der Datenbank erstellen, z

Zum Beispiel:

CREATE VIEW view_news AS
SELECT
  news.id news_id,
  user.id user_id,
  user.name user_name,
  [ OTHER FIELDS ]
FROM news, users
WHERE news.user_id = user.id;

Bei PHP:

$sql = "SELECT * FROM view_news";

Wie werden mehrdeutige Spaltennamen beim Abrufen von Ergebnissen aufgelost
Paolo Bergantino

Sie können so etwas tun

SELECT news.id as news_id, user.id as user_id ....

Und dann $row['news_id'] wird die Nachrichten-ID sein und $row['user_id'] wird die Benutzer-ID sein

1647948250 71 Wie werden mehrdeutige Spaltennamen beim Abrufen von Ergebnissen aufgelost
Guari

Ich hatte das gleiche Problem mit dynamischen Tabellen. (Tabellen, von denen angenommen wird, dass sie eine ID haben, um verknüpft werden zu können, aber ohne Annahme für den Rest der Felder.) In diesem Fall kennen Sie die Aliase nicht im Voraus.

In solchen Fällen können Sie zunächst die Tabellenspaltennamen für alle dynamischen Tabellen abrufen:

$tblFields = array_keys($zendDbInstance->describeTable($tableName));

Wobei $zendDbInstance eine Instanz von Zend_Db ist oder Sie können eine der Funktionen hier verwenden, um sich nicht auf Zend PHP PDO zu verlassen: Holen Sie sich den Spaltennamen einer Tabelle

Dann können Sie für alle dynamischen Tabellen die Aliase abrufen und $tableName.* für diejenigen verwenden, für die Sie keine Aliase benötigen:

$aliases = "";
foreach($tblKeys as $field)
    $aliases .= $tableName . '.' . $field . ' AS ' . $tableName . '_' . $field . ',' ;
$aliases = trim($aliases, ',');

Sie können diesen ganzen Prozess in eine generische Funktion packen und einfach saubereren Code haben oder fauler werden, wenn Sie möchten 🙂

1005470cookie-checkWie werden mehrdeutige Spaltennamen beim Abrufen von Ergebnissen aufgelöst?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy