Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit
GELÖST

3SQL Abfragen zu einer zusammenfassen? (kompl. problem - JOIN oder CASE?)

Frage Entwicklung Datenbanken

Mitglied: Igather

Igather (Level 1) - Jetzt verbinden

21.07.2010 um 20:27 Uhr, 3742 Aufrufe, 6 Kommentare

Hallo

Bin neu hier da ich hilfe für ein kompliziertes problem suche! Ich habe Grundkenntnisse in den gängigsten Webentwicklungssprachen und nun bin ich dabei, mein erstes Modul für Joomla zu schreiben. Folgendes Problem. Ich habe eine Tabelle mit allen Kommentaren meiner Community-Seite. Diese enthält kommentare jeweils zu Artikeln, Bildern und Videos.

Die (wesentliche) Struktur sieht so aus:

Kommentare: jos_jcomments

id - object_id - object_group - username - date usw.

Die object_id enthält jeweils den Schlüssel zu den anderen Komponenten, die object_group bezeichnet die andere komponente


Die anderen Tabellen haben folgende struktur

Bilder: jos_joomgallery

id - catid - imgtitle - imgdate - published


Artikel: jos_content

id - title - state - sectionid - catid


Videos: jos_hwdvidsvideos

id - title



Mein Modul soll die neuesten Kommentare seit dem letzten Login des Users ausgeben. Hier scheitert es bei mir, das ganze in eine Abfrage zusammenzufassen.

Wenn das Kommentar für ein Video verfasst ist, steht in der object_group die entsprechende komponente, in dem fall brauche ich dann aus der Videotabelle den Titel, bei einem Bilderkommentar brauche ich aus der Bildertabelle den Titel, und bei einem Artikelkommentar die category-id und den title (section-id um zu prüfen ob der artikel aus dem community-bereich stammt)

Diese 3 Abfragen machen genau das was ich möchte, habe sie auch erfolgreich über phpmyadmin getestet:

SELECT j.username,j.object_id,j.date,c.catid,c.title
FROM jos_jcomments AS j
INNER JOIN jos_content AS c ON c.id = j.object_id
WHERE j.date < '2010-07-21 00:09:37'
AND j.date > '2010-07-20 18:09:37'
AND j.published = 1
AND j.object_group = 'com_content'
ORDER BY j.date DESC

SELECT j.username, j.object_id, j.date, g.imgtitle
FROM jos_jcomments AS j
INNER JOIN jos_joomgallery AS g ON g.id = j.object_id
WHERE j.date < '2010-07-21 00:09:37'
AND j.date > '2010-07-20 18:09:37'
AND j.published =1
AND j.object_group = 'com_joomgallery'
ORDER BY j.date DESC

SELECT j.username, j.object_id, j.date, v.title
FROM jos_jcomments AS j
INNER JOIN jos_hwdvidsvideos AS v ON v.id = j.object_id
WHERE j.date < '2010-07-21 00:09:37'
AND j.date > '2010-07-20 18:09:37'
AND j.published =1
AND j.object_group = 'com_hwdvideoshare_v'
ORDER BY j.date DESC



Aber es ist doch möglich, dies alles in einer Abfrage zu machen, da ich den rückgabewert aus der funktion wieder zurückgeben muss, und der return kann ja nur ein array haben (die 3 ergebnisse in ein array zu packen ist doch unnötig)

So meine bisheringe Versuche sehen so aus:

$query = "SELECT j.username,j.date,j.object_group,j.object_id,cont.catid,cont.title AS artitle,gal.imgtitle AS imgtitle,vids.title AS vidtitle"
. "\n FROM #__jcomments AS j"
. "\n INNER JOIN #__content AS cont ON cont.id = j.object_id"
. "\n INNER JOIN #__joomgallery AS gal ON gal.id = j.object_id"
. "\n INNER JOIN #__hwdvidsvideos AS vids ON vids.id = j.object_id"
. "\n WHERE j.date < '$now'"
. "\n AND j.date > '$userlastvisit'"
. "\n AND j.published = 1 "
. "\n AND (cont.sectionid = '3' OR j.object_group = 'com_hwdvideoshare_v' OR j.object_group = 'com_joomgallery')"
. "\n ORDER BY j.date DESC"
;
$db->setQuery( $query );


Beim ausführen erhalte ich keine Fehlermeldung, aber das Query registriert nur die Kommentare zu der Komponenten joomgallery?

Mein anderer Lösungsansatz sieht so aus (hier ohne php da ich das direkt in phpmyadmin teste)

SELECT j.username,j.object_id,j.date
CASE j.object_group
WHEN 'com_content' THEN SELECT c.catid, c.title FROM c WHERE (c.id = j.object_id AND c.sectionid = '3')
WHEN 'com_joomgallery' THEN SELECT g.imgtitle FROM g WHERE g.id = j.object_id
WHEN 'com_hwdvideoshare_v' THEN SELECT v.title FROM v WHERE v.id = j.object_id
END CASE
FROM jos_jcomments AS j, jos_content AS c, jos_joomgallery AS g, jos_hwdvidsvideos AS v
WHERE j.date < '2010-07-21 00:09:37'
AND j.date > '2010-07-20 18:09:37'
AND j.published = 1
ORDER BY j.date DESC


Hierbei erhalte ich die Fehlermeldung:

#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 'CASE

Ich kann aber beim besten willen nicht rausfinden wo der syntaxfehler sein soll, habe schon viele verschiedene möglichkeiten probiert mit klammern usw.


Das Problem ist doch, dass das Array nachher verschiedene felder hat, die leer bleiben, da nur einige der kommentare eine cat_id haben. Ebenfalls ist ein problem, dass die object_id des kommentars die gleichen sein können in der content und joomgallery, so hatte ich bei einem test zwar dein eintrag, aber der link bei der ausgabe verwies hatte den falschen titel (es sollte ein bild sein aber es war der titel eines artikels)

(Das Modul soll am ende eine Liste ausgeben, wo der Verfasser des Kommentars steht, in welchem Bereich (also artikel oder bilder usw..), Link zu dem Artikel/Bild/Video und das Datum der Erstellung)

So also vielen Dank für alle die sich schonmal die mühe gemacht haben, das alles zu lesen, ich hoffe ich habe das Problem ausreichend beschrieben, bin wirklich dankbar über jede hilfe, da ich kein SQL-Profi bin! Falls noch irgendwelche Angaben benötigt werden, reiche ich es sofort nach! Ahso ich teste es auf einer aktuellen Xampp auf meinem Vista...

Danke!!!!
Mitglied: Biber
21.07.2010 um 21:42 Uhr
Moin Lgather,

willkommen im Forum.

Lass mal kurz die handwerklichen SQL-Befehle einen Moment beiseite.
Ist ja im ersten Schritt erstmal wichtiger die logische Struktur der Gesamtabfrage vor mindestens einem der geistigen Augen zu haben.

Wenn du einen oder anderthalb Schritte zurücktrittst und draufschaust, dann

  • ist sicherlich die Aussage "Die drei Einzelabfragen machen was sie sollen" richtig
01.
 
02.
SELECT j.username,j.object_id,j.date,c.catid,c.title 
03.
FROM jos_jcomments AS j 
04.
INNER JOIN jos_content AS c ON c.id = j.object_id 
05.
WHERE j.date < '2010-07-21 00:09:37' 
06.
AND j.date > '2010-07-20 18:09:37' 
07.
AND j.published = 1 
08.
AND j.object_group = 'com_content' 
09.
ORDER BY j.date DESC 
10.
 
11.
SELECT j.username, j.object_id, j.date, g.imgtitle 
12.
FROM jos_jcomments AS j 
13.
INNER JOIN jos_joomgallery AS g ON g.id = j.object_id 
14.
WHERE j.date < '2010-07-21 00:09:37' 
15.
AND j.date > '2010-07-20 18:09:37' 
16.
AND j.published =1 
17.
AND j.object_group = 'com_joomgallery' 
18.
ORDER BY j.date DESC 
19.
 
20.
SELECT j.username, j.object_id, j.date, v.title 
21.
FROM jos_jcomments AS j 
22.
INNER JOIN jos_hwdvidsvideos AS v ON v.id = j.object_id 
23.
WHERE j.date < '2010-07-21 00:09:37' 
24.
AND j.date > '2010-07-20 18:09:37' 
25.
AND j.published =1 
26.
AND j.object_group = 'com_hwdvideoshare_v' 
27.
ORDER BY j.date DESC
Was du danach versuchst, ist aber nicht "ich will das Beste, das Ergebnis aus Abfrage1 UND Abfrage2 UND Abfrage3 zusammenschaufeln",
sondern "Ich will EINE Abfrage, die mit den Bedingungen von Abfrage1 UND Abfrage2 UND Abfrage3 funktioniert."

Das ist inhaltlich etwas ganz anderes - so auch das Ergebnis.

(Wenn du nächstes Wochenende alle Frauen aus deiner Strasse einlädst, die ledig oder rothaarig oder unter 1,85m oder unter 20 sind, dann könnte es voll werden.
Wenn du nächstes Wochenende alle Frauen einlädst, die ledig und rothaarig und unter 1,85m und unter 20 sind, wird es ein anderes Ergebnis)

Ich würde in diesem Fall (kann ja sein, dass dein user Comments SOWOHL bei videos WIE AUCH bei Bilder WIE bei whatever stehen hat... oder nur eins von dreien..) zumindest als Proof-of-concept ein UNION ALL über alle drei Statements machen

01.
 
02.
SELECT all.Username, all.object_id, all.Date FROM ( 
03.
 
04.
SELECT j.username,j.object_id,j.date, 
05.
    -- c.catid, ?? Brauchst du die? 
06.
   c.title AS Title 
07.
FROM jos_jcomments AS j 
08.
INNER JOIN jos_content AS c ON c.id = j.object_id 
09.
WHERE j.published = 1 
10.
AND j.object_group = 'com_content' 
11.
 
12.
UNION ALL  
13.
SELECT j.username, j.object_id, j.date, g.imgtitle 
14.
FROM jos_jcomments AS j 
15.
INNER JOIN jos_joomgallery AS g ON g.id = j.object_id 
16.
-- WHERE  j.published =1 
17.
AND j.object_group = 'com_joomgallery' 
18.
 
19.
UNION ALL 
20.
 
21.
SELECT j.username, j.object_id, j.date, v.title 
22.
FROM jos_jcomments AS j 
23.
INNER JOIN jos_hwdvidsvideos AS v ON v.id = j.object_id 
24.
WHERE  j.published =1 
25.
AND j.object_group = 'com_hwdvideoshare_v' 
26.
) all 
27.
 
28.
where All.date j.date BETWEEN  '2010-07-20 18:09:37' and 2010-07-21 00:09:37' 
29.
 
30.
ORDER BY all.date DESC
[ungetestete Skizze]

...wie gesagt, als Proof-of-Concept.
Sollte das vom Ergebnis her plausibel, aber grotteninperformat sein, dann machen wir mir JOINs ein bisschen wat Flotteres.

Grüße
Biber
Bitte warten ..
Mitglied: Igather
21.07.2010 um 22:15 Uhr
Vielen Dank erstmal an dich Biber!

Also ich hoffe ich versteh das... *grübel*

Ahso, erstmal, das sind nicht die Kommentare eines Users, sondern diese Liste im Endergebnis soll sowas sein wie die letzten Beiträge in einem Forum, nur eben mit den Kommentaren.

Die catid aus der Tabelle jos_content brauche ich um den Link zu dem Artikel bei der Ausgabe erzeugen zu können.

Pro Kommentar kann ja nur einer der Fälle zutreffen, das Kommentar ist entweder ein Bilder, Artikel oder Videokommentar.

Die Bedingung mit dem Datum gilt für die Tabelle der Kommentare, ich möchte ja alle Kommentare herausholen, die zwischen jetzt und dem Datum des letzten Logins des Users vorhanden sind, also kann man das all.date rausnehmen? Das Datum des Artikels, Bildes oder Videos ist ja uninteressant, da hier lediglich die Kommentare benötigt werden.

Leider habe ich dein Query nicht testen können, es meldet mir einen Syntax-Fehler bei der Zeile 22, den ich aufgrund mangelnder Kenntnisse mit dem UNION nicht herausfinden kann. Mache mich erstmal schlau zum UNION...
Bitte warten ..
Mitglied: Igather
21.07.2010 um 22:34 Uhr
Ich glaub es ja nicht, es scheint zu funktionieren!

Das UNION ist nicht das richtige, soweit ich das überblicken kann, sondern ein LEFT JOIN anstatt des inner joins. Laut tutorial funktioniert ein LEFT join nämlich auch dann, wenn bestimmte Felder nicht ausgefüllt sind.

01.
        $query = "SELECT j.username,j.date,j.object_group,j.object_id,cont.catid,cont.title AS artitle,gal.imgtitle AS imgtitle,vids.title AS vidtitle" 
02.
               . "\n FROM (#__jcomments AS j" 
03.
               . "\n LEFT JOIN #__content AS cont ON cont.id = j.object_id)" 
04.
               . "\n LEFT JOIN #__joomgallery AS gal ON gal.id = j.object_id" 
05.
               . "\n LEFT JOIN #__hwdvidsvideos AS vids ON vids.id = j.object_id" 
06.
               . "\n WHERE j.date < '$now'" 
07.
               . "\n AND j.date > '$userlastvisit'" 
08.
               . "\n AND j.published = 1 " 
09.
               . "\n AND (cont.sectionid = '3' OR j.object_group = 'com_hwdvideoshare_v' OR j.object_group = 'com_joomgallery')" 
10.
               . "\n ORDER BY j.date DESC" 
11.
12.
        $db->setQuery( $query );
Diese Abfrage gibt zwar bei einem Query in phpmyadmin ein unschönes ergebnis, da z.B. ein Kommentar bei einem Video auch mit einem falschen Artikeltitel gefüllt wird.
Da ich aber in der Ausgabe des Moduls mit einem Switch-Case die object_group abfrage, ignoriere ich einfach den falschen titel und es funktioniert! Jedenfalls bei meinen ersten Tests.

Ist ja unglaublich!!!

Ich glaube das ist unschön programmiert im hinblick auf das SQL, da nicht-benötigte Einträge aus der DB geholt werden, aber ist das wichtig?
Bitte warten ..
Mitglied: Biber
22.07.2010 um 11:49 Uhr
Moin Igather,

sorry, dann hatte ich die Fragestellung doch falsch verstanden - ich war davon ausgegangen, dass in der Tat ein "sowohl als auch" bei Videos, Bildern und Artikeln da sein könnte.

Von daher vergiss diesen kleinen Exkurs mit UNION.
Der (erste) Syntaxfehler in meiner ungetesteten Skizze kommt sicherlich duch die Zeilen 15-17 zustande.
Da habe ich schlauerweise gleich die Zeile mit dem Schlüsselwort WHERE auskommentiert... das kann nicht fliegen.

Grüße
Biber
Bitte warten ..
Mitglied: Igather
22.07.2010 um 21:53 Uhr
Hi!

Das macht wirklich garnichts, vielen Dank nochmals für deine Hilfe!!!
Bitte warten ..
Mitglied: Biber
22.07.2010 um 22:08 Uhr
Moin lgather,

dann wenigstens noch ein Nachklapp zur Schadensbegrenzung:

01.
         
02.
                $query = "SELECT j.username,j.date,j.object_group,j.object_id,cont.catid,"  
03.
                         "\n CASE j.object_group " 
04.
                         "\n WHEN 'com_hwdvideoshare_v' Then vids.titel " 
05.
                         "\n WHEN 'com_joomgallery' Then gal.imgtitle " 
06.
                         "\n ELSE cont.title " END As Title 
07.
	               . "\n FROM (#__jcomments AS j" 
08.
	               . "\n LEFT JOIN #__content AS cont ON cont.id = j.object_id)" 
09.
	               . "\n LEFT JOIN #__joomgallery AS gal ON gal.id = j.object_id" 
10.
	               . "\n LEFT JOIN #__hwdvidsvideos AS vids ON vids.id = j.object_id" 
11.
	               . "\n WHERE j.date < '$now'" 
12.
	               . "\n AND j.date > '$userlastvisit'" 
13.
	               . "\n AND j.published = 1 " 
14.
	               . "\n AND (cont.sectionid = '3' OR j.object_group = 'com_hwdvideoshare_v' OR j.object_group = 'com_joomgallery')" 
15.
	               . "\n ORDER BY j.date DESC" 
16.
17.
        $db->setQuery( $query );
...um deinen ursprünglichen CASE-Käse-Gedanken neu zu beleben...

[auch wieder ungetestet... aber in dem Statement findest du glaub ich durch]

Grüße
Biber
Bitte warten ..
Neuester Wissensbeitrag
Windows 10

Powershell 5 BSOD

(8)

Tipp von agowa338 zum Thema Windows 10 ...

Ähnliche Inhalte
DSL, VDSL
Problem mit variernder Internetgeschwindigkeit (12)

Frage von schaurian zum Thema DSL, VDSL ...

Windows Netzwerk
gelöst Problem mit PSexec64 von Sysinternals (8)

Frage von MaxMoritz6 zum Thema Windows Netzwerk ...

Windows Server
gelöst Problem nach DC-Installation unter Server 2012 R2 (9)

Frage von manuel1985 zum Thema Windows Server ...

Heiß diskutierte Inhalte
Microsoft
Ordner mit LW-Buchstaben versehen und benennen (21)

Frage von Xaero1982 zum Thema Microsoft ...

Outlook & Mail
gelöst Outlook 2010 findet ost datei nicht (19)

Frage von Floh21 zum Thema Outlook & Mail ...

Netzwerkmanagement
gelöst Anregungen, kleiner Betrieb, IT-Umgebung (18)

Frage von Unwichtig zum Thema Netzwerkmanagement ...

Festplatten, SSD, Raid
M.2 SSD wird nicht erkannt (14)

Frage von uridium69 zum Thema Festplatten, SSD, Raid ...