[mySQL 5] Abfrage über mehrere Spalten - Ziel mehrere Spalten

Mc_Fly_B

Mitglied
... und blutiger Anfänger. ;)

Moin erstmal!

Habe eine Tabelle ge_board_content mit den Spalten content_id, board_id, parent_content_id, user_id, reply_to und views und weiteren.
Eine weitere Tabelle topics mit den Spalten id_topic, id_board, id_first_msg, id_member_started und num_views und weiteren.
Die fett geschriebenen sind PRIMARY und auto-increment. Gebe hier nur Spalten an, die vorerst wichtig erscheinen.

Nun soll topics.id_topic als sich erhöhender Zähler dienen. topics.id_board soll mit ge_board_content, topics.id_first_msg soll mit ge_board_content.content_id, topics.id_member_startet mit ge_board_content.user_id und topics.num_views mit ge_board_content.views befüllt werden, wenn ge_board_content.parent_content_id und ge_board_content.reply_to gleich "0" sind.

Ein erster Versuch mit nur einer Spalte:
SQL:
INSERT INTO topics( `id_first_msg` )
SELECT content_id FROM ge_board_content
WHERE((`ge_board_content`.`parent_content_id` =0)AND(`ge_board_content`.`reply_to` =0))

brachte die Fehlermeldung: #1062 - Duplicate entry '0-0' for key 2

Zumindest ist der Inhalt in der ersten Zeile korrekt. Nur wo hakt es? Und wie bekomme ich die anderen Spalten möglichst in einem Rutsch gefüllt? Und das ist auch nur der Anfang.

Mc Fly
 
Zuletzt bearbeitet von einem Moderator:
Gebe ich mehrere Spalten im INSERT INTO an:
SQL:
INSERT INTO topics ( `id_board`, `id_first_msg`, `id_member_started`, `num_views` )
SELECT board_id,content_id,user_id,views FROM ge_board_content
WHERE((`ge_board_content`.`parent_content_id` = 0) AND (`ge_board_content`.`reply_to` = 0))
ergibt das die Fehlermeldung: #1062 - Duplicate entry '0-7' for key 2

Das liegt offensichtlich an der Spalte topics.id_last_msg. Diese ist im Bezug auf topics.board_id auf UNIQUE gesetzt. Gleiches gilt auch für topics.id_first_msg. Ich muss also vorher noch den letzten Eintrag finden. Wenn ich da richtig liege, darf ich erst ge_board_content.parent_content_id mit der letzten Zeitangabe in ge_board_content.creation_datetime finden. Gleichzeitig kann ich auch noch ge_board_content.parent_content_id zählen und in topics.num_replies ablegen. Ich weiß aber erst nach dem WHERE um welche ge_board_content.content_id es sich handelt, die ich nach dem letzten Eintrag abfragen und auch zählen kann.

Ich hatte ja schon befürchtet, dass es kompliziert wird... ;)

Mc Fly
 
Zuletzt bearbeitet von einem Moderator:
Kompliziert ist es nicht unbedingt. Ich versteh nur noch nicht was du da machen willst.
 
Die erste Tabelle ist so ein Forum unbekannten Formats. Wurde mal irgendwann von jemandem selbst verfasst. Ist absolut nicht mehr up-to-date.

Die zweite Tabelle ist die smf_topics von SMF2. Und da sollen nun die Verlinkungen zum Inhalt (smf_messages) aus dem alten Forum hinein. Also im Grunde eine "simple" Konvertierung. Wobei der Inhalt aus dem alten Forum in einer Tabelle liegt, inklusive der Board- und Topic-Angaben, während es in SMF2 getrennt in zwei Tabellen liegt. Der Inhalt selbst machte weniger Schwierigkeiten.

Mc Fly
 
Zuletzt bearbeitet:
Lasse ich die fehlerhafte zweite Anweisung durchlaufen, habe ich zumindest schon mal zwei Zeilen in der topics.

Damit kann ich schon mal die Abfrage zum Zählen testen:
SQL:
SELECT `topics`.`id_first_msg`,COUNT(*)
FROM `ge_board_content`,`topics`
WHERE `ge_board_content`.`parent_content_id`=`topics`.`id_first_msg`
GROUP BY `topics`.`id_first_msg`
Funktioniert... :) Liefert zwei korrekte Ergebnisse die ich in `topics`.`num_replies` einfügen kann.

Nun zum Lokalisieren des letzten Eintrags... wir schreiten voran.

Mc Fly
 
Zuletzt bearbeitet von einem Moderator:
Letzter Eintrag ist auch gefunden:

SQL:
SELECT `parent_content_id` , `content_id` , MAX( `creation_datetime` )
FROM `ge_board_content`
WHERE `parent_content_id` <> 0
GROUP BY `parent_content_id`

Habe Stichproben per Hand überprüft: Stimmt! :)

Und nun den ganzen Abfragenwust zu einem Stück verschmelzen... :confused: ... arbeite mich weiter voran.

Mc Fly
 
Zuletzt bearbeitet von einem Moderator:
Stehe jetzt etwas auf dem Schlauch. Sehe den Wald vor lauter Bäumen nicht mehr... :confused:

Wie bekomme ich den Wert für `ge_board_content`.`content_id` aus dieser Abfrage:
SQL:
SELECT `parent_content_id` , `content_id` , MAX( `creation_datetime` )
FROM `ge_board_content`
WHERE `parent_content_id` <> 0
GROUP BY `parent_content_id`

als `topics`.`id_last_msg` in diese INSERT INTO:
SQL:
INSERT INTO topics ( `id_board`, `id_first_msg`, `id_last_msg`, `id_member_started`, `num_views` )

Mir qualmt so langsam der Schädel... ;)

Mc Fly
 
Zuletzt bearbeitet von einem Moderator:
Bin jetzt doch einigermaßen verwirrt!

Folgende Abfrage brachte korrekte Ergebnisse bezüglich des Datums des letzten Eintrags für ein Topic:
SQL:
SELECT `parent_content_id` , MAX( `creation_datetime` )
FROM `ge_board_content`
GROUP BY `parent_content_id`

Da ich aber zur Weiterverarbeitung noch die `content_id` dazu benötige aber die "0"-Einträge von `parent_content_id` nicht, habe ich diese Abfrage erweitert:
SQL:
SELECT `parent_content_id` , `content_id` , MAX( `creation_datetime` )
FROM `ge_board_content`
WHERE `parent_content_id` <> 0
GROUP BY `parent_content_id`

Diese Abfrage bringt mir zwar immer noch das letzte Datum, aber dieses passt nicht zu `content_id`!?

Ok! Habe noch etwas probiert:
SQL:
SELECT `parent_content_id` , MAX( `content_id` ) , MAX( `creation_datetime` )
FROM `ge_board_content`
WHERE `parent_content_id` <> 0
GROUP BY `parent_content_id`

Auch hier passt das Ergebnis nicht, da das alte System offensichtlich die IDs von gelöschten Einträgen wieder verwendet hat...

Mc Fly
 
Zuletzt bearbeitet von einem Moderator:
Zur Umgehung der Schlüssel habe ich mir damit geholfen, dass ich, anstatt den letzten Eintrag abzufragen, erstmal den ersten dort rein gesetzt habe:
SQL:
INSERT INTO topics ( `id_board`, `id_first_msg`, `id_last_msg`, `id_member_started`, `num_views` )
SELECT board_id,content_id,content_id,user_id,views FROM ge_board_content
WHERE((`ge_board_content`.`parent_content_id` = 0) AND (`ge_board_content`.`reply_to` = 0))

Will ich nun die letzten Einträge berechnen, liefert mir z. B. :
SQL:
SELECT `content_id`
FROM `ge_board_content`
WHERE (SELECT MAX(`creation_datetime`)
              FROM `ge_board_content`
              ) AND `parent_content_id` <> 0
GROUP BY `parent_content_id`

genau eine Spalte mir den benötigten und korrekten Werten zurück.

Wie bekomme ich diese Werte nun an die richtige Stelle?
SQL:
UPDATE smf_topics , ge_board_content
SET smf_topics.id_last_msg = ge_board_content.content_id
WHERE (SELECT MAX(`creation_datetime`)
              FROM `ge_board_content`
              WHERE `parent_content_id` <> 0
GROUP BY `parent_content_id`)

Funktioniert ja nicht, da logischerweise Fehlermeldung #1242 - Subquery returns more than 1 row

Mc Fly
 
Zuletzt bearbeitet von einem Moderator:
Zurück