Hallo, lieber Forumbenutzer. Wir haben in letzter Zeit festgestellt, dass die Kommunikation via Slack viel schneller und zielführender ist als ein Beitrag im Forum. Aufgrund der neuen Möglichkeiten der Kommunikation ist das Forum ein wenig eingeschlafen und weniger Nutzer benutzen das Forum aktiv (trotzdem lohnt es sich evtl. hier nach Lösungen zu suchen oder seine Frage zu stellen).

Wir empfehlen, für deine Fragen/Probleme aktuell (zusätzlich) Slack zu nutzen. Dort sind viele kompetente Benutzer aktiv und beantworten jegliche Fragen, gerne auch von REDAXO-Anfängern! Slack wird von uns sehr intensiv und meistens "rund um die Uhr" benutzt :-)
Selbst einladen kannst Du dich hier: http://redaxo.org/slack/
Meusi
Beiträge: 158
Registriert: 18. Mär 2009, 16:18

Komplizierte MYSQL Abfrage

25. Mär 2013, 16:27

Hallo Leute..

ich verzweifel :(
ich hab 2 Tabellen: Projekte und Meilensteine..
Projekte:
id, name, en_datum, person, ....
Meilensteine:
id, name, proj_id, date, fertig

ich möchte gerne die Projekte angezeigt haben, jedoch soll es nach den Meilensteinen sortiert sein.
Sprich wenn ein Meilenstein am 21.04.2012 erstellt worden ist, soll es vor den Projekt stehen, welches ein Meilenstein am 24.04.2012 erstellt hat UND gleichzeit soll es vor den Projekten stehen wo 'en_datum' auch noch danach ist.

sprich erst nach meilensteindatum sotieren und danach den en_datum vom Projekten.

Mein SQL Code:

Code: Alles auswählen

SELECT p.person, p.id 
	FROM ".PREFIX."projekte p, ".PREFIX."meilensteine m
	WHERE m.proj_id = p.id
	AND m.fertig = 0
	GROUP BY p.id 
	ORDER BY m.date, p.en_datum
er funkntioniert schon super :) ich bekomm fast alle einträge zurück und richtig sortiert.
Er zeigt mir nur projekte an, wo auch ein dazugehöriger Meilenstein vorhanden ist UND wo ein Meilenstein noch nicht fertig ist..

ich möchte gerne alle Projekte angezeigt haben, egal ob die ein Meilenstein haben oder ob alle Meilensteine schon fertig sind.

ich hoffe ihr könnt mir irgendwie helfen :)
Folgende Threads stehen offen:

Benutzeravatar
Xong
Beiträge: 2081
Registriert: 5. Jun 2008, 08:30
Wohnort: Halle (Saale)

Re: Komplizierte MYSQL Abfrage

25. Mär 2013, 16:51

Hallo Meusi,

du verwendest die implizite Schreibweise des INNER JOINs. Das solltest du generell vermeiden, um die Lesbarkeit der SQL-Statements zu erhöhen:

Code: Alles auswählen

SELECT
  p.person,
  p.id
FROM ".PREFIX."projekte p
INNER JOIN ".PREFIX."meilensteine m
  ON m.proj_id = p.id
WHERE 1
  AND m.fertig = 0
GROUP BY p.id
ORDER BY m.date, p.en_datum
Das Problem beim INNER JOIN ist, dass nur Datensätze ausgegeben werden, die eine über die ON-Klausel mitgeteilte Entsprechung in der zweiten Relation haben.
Du möchtest aber auf jeden Fall alle Datensätze der ersten Relation. Dafür brauchst du aber keinen INNER sondern einen LEFT (OUTER) JOIN. Und weil wir ja das Statement schon umgeschrieben haben, dürfte es jetzt ein Leichtes sein, das umzuändern. ;)

Falls dich das Thema interessiert, findest du bei Selfhtml einen einsteigerfreundlichen Artikel: http://aktuell.de.selfhtml.org/artikel/ ... ken/joins/

Edit: Beim Ändern des SQL-Statements musst du außerdem die WHERE-Klausel so erweitern, dass m.fertig auch NULL sein kann. Oder du nimmst die Bedingung mit in die ON-Klausel.
LG,
Xong

Bild Määääääääääääääääääääääääh!

Meusi
Beiträge: 158
Registriert: 18. Mär 2009, 16:18

Re: Komplizierte MYSQL Abfrage

25. Mär 2013, 17:32

hab jetzt LEFT JOIN benutzt:

Code: Alles auswählen

SELECT
	  p.person,
	  p.id
	FROM ".PREFIX."projekte p
	LEFT JOIN ".PREFIX."meilensteine m
	  ON m.proj_id = p.id AND m.fertig = 0
	GROUP BY p.id
	ORDER BY m.date, p.en_datum
jedoch sortiert er nur nach p.en_datum und ingoert vollkommend den m.date :)

ich möchte so sortieren, dass m.date und p.en_datum gleiche prorietäten hat und dann sortiert.
vllt kann ich das mit php leider erklären:

Code: Alles auswählen

if($m.date < $p.en_datum) $datum = $m.date;
else $datum = $p.en_datum;
SORTIEREN NACH $datum
Aber danke schonmal :) jetzt werden schon bei mir alle (690) Einträge angezeigt :P

EDIT: deinen Link hab ich mir durchgelesen und fands sehr interesannt.. vielleicht sollte ich noch dazu anmerken, dass es mehre Meilensteine für ein Projekt gibt. und ich möchte hal nur die Meilensteine auslesen wo noch nicht fertig (m.fertig = 0) sind :)
Folgende Threads stehen offen:

Benutzeravatar
Xong
Beiträge: 2081
Registriert: 5. Jun 2008, 08:30
Wohnort: Halle (Saale)

Re: Komplizierte MYSQL Abfrage

25. Mär 2013, 17:39

Hi Meusi,

welchen Datentyp haben die Sortierspalten?
LG,
Xong

Bild Määääääääääääääääääääääääh!

Meusi
Beiträge: 158
Registriert: 18. Mär 2009, 16:18

Re: Komplizierte MYSQL Abfrage

25. Mär 2013, 17:45

INT(16) falls du das meinst :)

weil sie in Unix-Zeitformat gespeichert wird
Folgende Threads stehen offen:

Benutzeravatar
Xong
Beiträge: 2081
Registriert: 5. Jun 2008, 08:30
Wohnort: Halle (Saale)

Re: Komplizierte MYSQL Abfrage

25. Mär 2013, 18:24

Hi Meusi,

der Datentyp passt.

Dann liegt dein Problem wohl an den Projekten, die keine Meilensteine haben. Deren m.date ist durch den LEFT JOIN automatisch NULL und sie werden deshalb automatisch an den Anfang gesetzt.

Vielleicht passt ja diese Abfrage besser:

Code: Alles auswählen

(SELECT
  p.person,
  p.id,
  1 as sort,
  m.date,
  p.en_datum
FROM ".PREFIX."projekte p
INNER JOIN ".PREFIX."meilensteine m
  ON m.proj_id = p.id AND m.fertig = 0
GROUP BY p.id)

UNION

(SELECT
  p.person,
  p.id,
  2 as sort,
  0 as date,
  p.en_datum
FROM ".PREFIX."projekte p
WHERE p.id NOT IN (SELECT proj_id FROM ".PREFIX."meilensteine))

ORDER BY sort, date, en_datum
Ich bin mir nicht sicher, ob das so funktioniert und ob das der eleganteste Weg ist. Wenn du noch Hilfe brauchst, kannst du dich ja nochmal melden.
LG,
Xong

Bild Määääääääääääääääääääääääh!

Meusi
Beiträge: 158
Registriert: 18. Mär 2009, 16:18

Re: Komplizierte MYSQL Abfrage

26. Mär 2013, 09:50

Hey :) danke, aber das passt immer noch nicht :)

du tuhst erst den 1ten SQL abfrage eine höhere Priorität geben als den 2ten :)
ich möchte es gerne so haben:

en_datum = Zielterim (en = ende)

Projekt1:
Zieltermin: 08.06.13
Meilensteine: 02.05.13, 15.05.13

Projekt2:
Zieltermin: 14.05.13
Meilensteine: 30.04.13, 05.05.13

Projekt3:
Zieltermin: 20.07.13
Meilensteine: 13.04.13, 01.05.13

Projekt4:
Zieltermin: 05.06.13
Meilensteine: KEINE

Wenn man nach Zieltermin sortiert kommt:
Projekt2, Projekt4, Projekt1, Projekt3

Wenn man nach Meilensteine sortiert kommt:
Projekt4 (NULL)
Projekt3 (13.04.13)
Projekt2 (30.04.13)
Projekt1 (02.05.13)

Nun möchte ich aba das beide Datums (??) gleichgesetzt wird:

Projekt3 (13.04.13 - Meilenstein)
Projekt2 (30.04.13 - Meilenstein)
Projekt1 (02.05.13 - Meilenstein)
Projekt4 (05.06.13 - Zieltermin)

Vielleicht ist das so leichter zu verstehen :)

Dein Code kann schon vielleicht richtig funktionieren, aber er setzt die Projekte, die kein Meilenstein haben nach ganz hinten

MFG Meusi
Folgende Threads stehen offen:

Benutzeravatar
Xong
Beiträge: 2081
Registriert: 5. Jun 2008, 08:30
Wohnort: Halle (Saale)

Re: Komplizierte MYSQL Abfrage

26. Mär 2013, 10:02

Hi Meusi,

versuch´s mal damit:

Code: Alles auswählen

SELECT
  p.person,
  p.id
FROM ".PREFIX."projekte p
  LEFT JOIN ".PREFIX."meilensteine m
ON m.proj_id = p.id AND m.fertig = 0
GROUP BY p.id
ORDER BY CASE WHEN m.date IS NOT NULL THEN m.date ELSE p.en_datum END
LG,
Xong

Bild Määääääääääääääääääääääääh!

Meusi
Beiträge: 158
Registriert: 18. Mär 2009, 16:18

Re: Komplizierte MYSQL Abfrage

26. Mär 2013, 10:18

sieht vielversprechend aus :D

und es funktioniert perfekt *____*

Vielen Dank an dir mein PHP-Gott :D

hab noch das Group BY gelöscht, da ich ja mit "INNER JOIN" gearbeitet hab und somit das gleiche Projekt gleichzeitig mehrmals drin war (weil es ja mehr Meilensteine hatte :D)

DANKE nochmal :)

EDIT: hab noch abgefragt ob der Meilensteindatum kleiner ist als der Zieltermin:

mein fertiger Code:

Code: Alles auswählen

SELECT
  p.person,
  p.id
FROM ".PREFIX."projekte p
  LEFT JOIN ".PREFIX."meilensteine m
ON m.proj_id = p.id AND m.fertig = 0
ORDER BY CASE WHEN m.date IS NOT NULL AND m.date < p.en_datum THEN m.date ELSE p.en_datum END
Folgende Threads stehen offen:

Zurück zu „Sonstiges“