php.de

Zurück   php.de > Webentwicklung > Datenbanken

Datenbanken SQL und Co

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 06.01.2010, 22:57  
Neuer Benutzer
 
Registriert seit: 06.01.2010
Beiträge: 2
PHP-Kenntnisse:
Anfänger
OldDragon befindet sich auf einem aufstrebenden Ast
Standard Abfrage/Ausgabe bei m:n Beziehung

Halli hallo,

ich habe ein kleines Beziehungsproblem und hoffe, dass mir jemand bei der Ausgabe/Abfrage von Tabellen mit n:m-Beziehung helfen kann.

Die Tabellen sehen so aus:

Code:
CREATE TABLE `nt_notes` (
  `id` int(11) NOT NULL auto_increment,
  `title` varchar(255) collate latin1_german2_ci default NULL,
  `note` text collate latin1_german2_ci,
  `date` int(11) NOT NULL default '0',
  `date_changed` int(11) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 COLLATE=latin1_german2_ci;

CREATE TABLE `nt_tags` (
  `id` int(11) NOT NULL auto_increment,
  `tag` varchar(255) collate latin1_german2_ci NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 COLLATE=latin1_german2_ci;

CREATE TABLE `nt_tags_notes` (
  `id_notes` int(11) NOT NULL default '0',
  `id_tags` int(11) NOT NULL default '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_german2_ci;

nt_notes enthält Notizen, nt_tags enhält Tags zu den Notizen und nt_tags_notes verknüpft die beiden über die IDs.

Nun möchte ich einfach eine Liste der Notizen ausgeben und zu jeder Notiz die entsprechenden Tags. Momentan frage ich dazu nt_notes ab und in der while-Schleife dann jeweils extra nach den Tags, was natürlich bei größer werdender Datenmenge nicht so performant ist.

Um alles in einer Abfrage zu bekommen, würde ich es mit folgendem versuchen:
Code:
SELECT nt_notes.id,
  nt_notes.title,
  nt_notes.note,
  nt_tags_notes.id_tags,
  nt_tags_notes.id_notes,
  nt_tags.id,
  nt_tags.tag,
  nt_tags_notes.id_notes
FROM nt_notes, nt_tags_notes, nt_tags
WHERE (nt_notes.id = nt_tags_notes.id_notes)
  AND (nt_tags.id = nt_tags_notes.id_tags)
Da fehlen dann aber die notes, die keine passenden Einträge in Tags haben. Vermute, dass ich ein (LEFT) JOIN benötige, habe aber keine Ahnung, wie ich das einsetzen kann.

Seh ich dass richtig, dass ich die durch mehrere Tags erhaltenen doppelten Zeilen, die sich nur durch die Tas unterscheiden, nur manuell per PHP rausfiltern kann (Gruppenwechsel)?

Freue mich auf hilfreiche Antworten,
od
OldDragon ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 07.01.2010, 01:23  
da schreibt der ElePHPant
 
Benutzerbild von Flor1an
 
Registriert seit: 18.06.2008
Beiträge: 8.903
PHP-Kenntnisse:
Fortgeschritten
Flor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer Anblick
Standard

Bei Beziehungsproblemen am besten zur Eheberatung gehen

Gibt jetzt zwei Möglichkeiten bei dir.

Entweder genau so wie du es beschrieben hast. Einen LEFT JOIN, somit bekommst du jeden Note (auch die ohne Tag). Allerdings dann eben jede Note auch mehrfach, für jeden Tag eben einmal. Gruppenbruch wäre da dann eine Möglichkeit.

Besser wäre aber wohl die MySQL Funktion GROUP_CONCAT zu nutzen. Damit kannst du direkt in MySQL alle Tags zusammenbauen.

Beispiel:
Code:
SELECT
  n.id,
  n.title,
  n.note
  GROUPT_CONCAT(t.tag) AS tags
FROM  nt_notes AS n

LEFT JOIN nt_tags_notes AS nt
ON        n.id = nt.id_notes

LEFT JOIN nt_tags AS t
ON        t.id = nt.id_tags

GROUP BY n.id
Damit bekommst du alle Notes und wenn Tags existieren bekommst du alle Tags in einem String zurück. Ein Beispiel Ergebnis das dann in der Spalte "tags" steht wäre: tag1,tag2,tag3

Somit hast du pro Note nur noch einen Datensatz, kannst dann mit PHP sehr einfach entscheiden was du mit den Tags machen willst (also entweder direkt so verwenden wenn sie nur ausgegeben werden sollen oder einfach am Komma trennen.
Flor1an ist offline   Mit Zitat antworten
Alt 07.01.2010, 15:12  
Neuer Benutzer
 
Registriert seit: 06.01.2010
Beiträge: 2
PHP-Kenntnisse:
Anfänger
OldDragon befindet sich auf einem aufstrebenden Ast
Standard

Na das ist ja schon mal ne chice Antwort.
Ich bekomm ich aber leider nen fehler:

#1064 - You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the right syntax to use near '( t.tag ) AS tags FROM nt_notes AS n LEFT JOIN nt_tags_notes AS nt ON n.id =' at line 1


Wenn ich die Zeile mit dem GROUPT_CONCAT(t.tag) AS tags weglasse wird die Abfrage ausgeführt, jedoch natürlich ohne die Tags auszugeben.

Die Abfrage mit dem Gruppenbruch würde mich eigentlich generell auch interessieren, falls ich die Tabelle mit den Tags noch um weitere Felder erweitere.

Hab mal ein wenig experimentiert ob ich ohne das concat was sinnvolles erhalte:
wenn ich im select nt_tags.tags oder t.tags mit gibt es nen Syntaxfehler. Wenn ich * nehme, dann nicht, anscheinend werden durch das GROUP BY n.id einige Zeilen weggelassen, ohne sieht die Ausgabe schon ganz brauchbar aus. also
Code:
SELECT
*
FROM  nt_notes AS n

LEFT JOIN nt_tags_notes AS nt
ON        n.id = nt.id_notes

LEFT JOIN nt_tags AS t
ON        t.id = nt.id_tags
Wie sortier ich das nun z.B. nach Datum? Wo müsste das ORDER BY hin, so dass die Zeilen mit den Tags zu ner Note immer noch aufeinander folgen? Würde dann das auseinanderklamüsern per PHP machen.
OldDragon ist offline   Mit Zitat antworten
Alt 07.01.2010, 15:36  
Erfahrener Benutzer
 
Registriert seit: 25.09.2009
Beiträge: 2.114
PHP-Kenntnisse:
Fortgeschritten
BlackScorp wird schon bald berühmt werdenBlackScorp wird schon bald berühmt werden
Standard

die alias bezeichnungen bei tabellen macht man ohne AS einfach nur tabellenname aliasname
__________________
Mein kleines Projekt
-Cruel Online-
5 von 3 Leuten können kein Bruchrechnen
BlackScorp ist offline   Mit Zitat antworten
Alt 07.01.2010, 16:29  
Moderator
 
Benutzerbild von Chriz
 
Registriert seit: 11.05.2008
Beiträge: 6.266
Chriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer Anblick
Standard

Hallo,

statt der Selektion in while() kannst du die Tags auch dabei sammeln und diese später gesammelt abfragen und zuordnen. Das kostet dich zwar mehr Schleifen in PHP, aber du vermeidest damit Queries innerhalb von Schleifen, was eben teilweise sehr stark an die Performanz gehen kann.

In drei Abfragen kannst du damit alle Werte und Zuordnungen erhalten.

1. Notes sammeln (SELECT * FROM nt_notes)
2. diese Notes in der Zuordnungstabelle selektieren, Tags selektieren (SELECT notes_id, tags_id FROM notes_with_tags WHERE notes_id IN ($noteIds))
3. Tags herausfischen und per Query aus der Datenbank ziehen (SELECT * FROM nt_tags WHERE id IN ($tagIds))
4. Zuordnung herstellen, die durch Punkt 2 bekannt ist (PHP-seitig)

Geändert von Chriz (07.01.2010 um 16:32 Uhr).
Chriz ist offline   Mit Zitat antworten
Alt 07.01.2010, 21:24  
da schreibt der ElePHPant
 
Benutzerbild von Flor1an
 
Registriert seit: 18.06.2008
Beiträge: 8.903
PHP-Kenntnisse:
Fortgeschritten
Flor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer Anblick
Standard

Zitat:
Zitat von BlackScorp Beitrag anzeigen
die alias bezeichnungen bei tabellen macht man ohne AS einfach nur tabellenname aliasname
Muss nicht bei MySQL, kann auch mit AS gemacht werden.
Flor1an ist offline   Mit Zitat antworten
Alt 08.01.2010, 13:24  
Erfahrener Benutzer
 
Registriert seit: 25.09.2009
Beiträge: 2.114
PHP-Kenntnisse:
Fortgeschritten
BlackScorp wird schon bald berühmt werdenBlackScorp wird schon bald berühmt werden
Standard

Zitat:
Zitat von Flor1an Beitrag anzeigen
Muss nicht bei MySQL, kann auch mit AS gemacht werden.
ach kommt von wenn man ständig mit oracle arbeitet
__________________
Mein kleines Projekt
-Cruel Online-
5 von 3 Leuten können kein Bruchrechnen
BlackScorp ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
[Erledigt] LEFT JOIN Daten ausgeben bei 1:n Beziehung Asipak PHP Tipps 2009 11 01.08.2009 15:27
MySQL, Suche - Volltext o. Beziehung shoq Datenbanken 1 13.07.2009 15:27
[Erledigt] MYSQL Beziehung likemike90 Datenbanken 38 08.01.2009 21:59
m:n Beziehung verwalten csc Datenbanken 5 07.01.2009 19:54
Formular für 1:n Beziehung DDuff PHP Tipps 2008 3 27.03.2008 05:17
abfrage aus zwei tabellen mit beziehung Dilandau Datenbanken 17 11.01.2007 19:06
n:m beziehung, zuordung von mehrer datensätzen zu einander Crypi Datenbanken 2 14.09.2006 11:27
[Erledigt] Beziehung Datenbanken 1 08.07.2005 09:29
Abfrage-Rückgabe mit beziehung aus 2ter Tabelle Datenbanken 3 17.02.2005 21:34
Problem bei einer Klasse mit "hat" beziehung PHP Tipps 2004 4 06.10.2004 21:29
Tabellen in Beziehung setzen!! Boennchen Datenbanken 4 23.07.2004 13:20

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
mysql m:n select abfrage, m:n beziehung, m n beziehung, m zu n beziehung abfragen, http://www.php.de/datenbanken/63068-abfrage-ausgabe-bei-m-n-beziehung.html, mysql zuordnungstabelle where mehrfach, gruppenbruch php, m zu n beziehung mysql, n zu m beziehung abfrage, join m n relation, abfrage m:n beziehung, php gruppenwechsel, mysql m:n beziehung auslesen, n m beziehung join, join bei m n beziehung, sql n:m beziehung abfragen, mysql m:n beziehungen, php mysql beziehungen abfragen, sql m:n beziehung join, mysql n:m tabellen titel

Alle Zeitangaben in WEZ +2. Es ist jetzt 09:29 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum