it-swarm.com.de

PHP & MYSQL: Wie werden mehrdeutige Spaltennamen im JOIN-Vorgang aufgelöst?

Ich habe zwei Tabellen in meiner Datenbank:

NEWS ('id' - die Nachrichten-ID, 'user' - die Benutzer-ID des Autors)

USERS ('id' - die Benutzer-ID)

Ich möchte jetzt einen SELECT * FROM news JOIN users ON news.user = user.id Erstellen, wenn ich die Ergebnisse in PHP=) erhalte, ist das ungefähr so:

$row = mysql_fetch_array($result), und erhalte Spaltennamen mit $row['column-name'] ... wie erhalte ich die Nachrichten-ID und die Benutzer-ID mit demselben Spaltennamen?

UPDATE: Vielen Dank für die schnellen Antworten. Aliase scheinen die beste Lösung zu sein.

71
Dan Burzo

Sie können Aliase für die von Ihnen 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'
115
CMS

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

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

40
Greg

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

Ich gehöre zu den Faulen, die nicht jeden Spaltennamen mit einem Tabellenpräfix aliasen oder ausschreiben wollen.

Sie können alle Spalten aus einer bestimmten Tabelle auswählen, indem Sie in Ihrer select-Anweisung table_name.* Verwenden.

Wenn Sie Spaltennamen dupliziert haben, wird MySQL vom ersten bis zum letzten überschrieben. Die Daten aus dem ersten duplizierten Spaltennamen werden überschrieben, wenn dieser Spaltenname erneut angetroffen wird. Der doppelte Spaltenname, der zuletzt eingegeben wurde, gewinnt also.

Wenn ich 3 Tabellen mit jeweils einem doppelten Spaltennamen verknüpfe, 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 stammt der Wert von dup, den ich erhalte, aus table3.

Was ist, wenn ich möchte, dass dup der Wert von table1 Ist?

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 kommt table1 Als letztes, also wird der Wert von dup der Wert von Tabelle1 sein.

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

Ich weiß, dass der Wert von dup in allen 3 Tabellen gleich sein sollte, aber was ist, wenn table3 Keinen passenden Wert für dup hat? Dann wäre dup im ersten Beispiel leer, und das wäre ein Mist.

21
Eab

Ein weiterer Tipp: Wenn Sie einen saubereren PHP Code haben möchten, können Sie eine VIEW in der Datenbank erstellen, z.

Beispielsweise:

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;

In PHP:

$sql = "SELECT * FROM view_news";
9
Dirk

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

Wenn Sie in PHP MYSQL_NUM In mysql_fetch_array() verwenden, erhalten Sie alle Spalten. Das Problem ist, wenn Sie mysql_fetch_array() mit MYSQL_ASSOC Verwenden. Dann baut PHP in 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 aus Tabelle3. Das Problem ist, dass eine Ergebnismenge aus MySQL Spalten mit demselben Namen enthalten kann, aber assoziative Arrays in PHP keine doppelten Schlüssel in Arrays zulassen. Wenn die Daten in assoziativen Arrays in PHP gespeichert werden, gehen einige Informationen unbemerkt verloren ...

8
GoTo

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'] ist die Benutzer-ID

8

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, ohne dass dies für die übrigen Felder angenommen wird.) In diesem Fall kennen Sie die Aliase nicht im Voraus.

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

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

Wobei $ zendDbInstance eine Instanz von Zend_Db ist oder Sie eine der Funktionen hier verwenden können, um sich nicht auf Zend zu verlassen php pdo: Hole 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 gesamten Prozess in eine generische Funktion zusammenfassen und nur saubereren Code haben oder fauler werden, wenn Sie möchten :)

2
haknick

Wenn Sie keine Lust auf Aliassing haben, können Sie auch einfach die Tabellennamen voranstellen.

Auf diese Weise können Sie die Generierung Ihrer Abfragen besser automatisieren. Außerdem ist es eine bewährte Methode, select * nicht zu verwenden (es ist offensichtlich langsamer als nur die Felder auszuwählen, die Sie benötigen Außerdem sollten Sie nur explizit die Felder benennen, die Sie haben möchten.

SELECT
    news.id, news.title, news.author, news.posted, 
    users.id, users.name, users.registered 
FROM 
    news 
LEFT JOIN 
    users 
ON 
    news.user = user.id
1
SchizoDuckie