5322
Goto Top

MySQL Left Join sortieren

Hallo zusammen,
Habe ein Problem mit einem MySQL - Befehl:

SELECT
member.id,
member.membername,
urlaub.urlaubanfang,
urlaub.urlaubende,
urlaub.urlaubinfo
FROM member
LEFT JOIN urlaub
ON urlaub.memberid = member.id
GROUP BY member.id

Der funktioniert soweit, einzigstes Problem ist das ich immer den ersten Urlaub des Members aus der Tabelle urlaub bekomme. Möchte aber den haben, der als nächstes kommt! Kann ja sein das da die Reihenfolge nicht richtig ist. Möchte also praktisch den LEFT JOIN sortieren!
Kann mir da eben einer helfen!?
Mit ORDER BY member.id, urlaub.urlaubanfang klappts nicht, da krieg ich die Endtabelle nach memberid und urlaubsanfang sortiert...

Vielen Dank im Vorraus!

Content-Key: 16875

Url: https://administrator.de/contentid/16875

Printed on: April 23, 2024 at 12:04 o'clock

Mitglied: 16640
16640 Sep 28, 2005 at 10:25:41 (UTC)
Goto Top
tja, da fehlt Dir wohl eine WHERE-Bedingung face-wink

SELECT blafasel FROM ... die JOINS WHERE urlaub.urlaubanfang größer als GETDATE() GROUP ...

größer als soll eigentlich eine schließende spitze Klammer sein, aber das unterdrückt die Boardsoftware.

Ich weiss nicht, ob MySQL die GETDATE()-Funktion kennt. Ansonsten musst Du da die analoge Funktion für den aktuellen Timestamp einsetzen.

dba
Mitglied: 5322
5322 Sep 28, 2005 at 10:30:27 (UTC)
Goto Top
hallo,
da bekomme ich aber nicht zwangsläufig den nächsten urlaub zurück, sondern nur einen, der größer als "jetzt" ist... das kann auch der übernächste urlaub sein.
ciao!
Mitglied: 16640
16640 Sep 28, 2005 at 10:50:55 (UTC)
Goto Top
Was genau willst Du denn in dem Resultset haben und wie soll es ggf. sortiert sein?

dba
Mitglied: 5322
5322 Sep 28, 2005 at 11:40:18 (UTC)
Goto Top
ich muss nach einem feld in der tabelle urlaub sortieren können; ich sag jetzt mal bevor diese mit der tabelle member verknüpft wird. da ich ein group by mit dabei habe um nur einen datensatz pro member anzuzeigen kann ich nicht kontrollieren mit welchem urlaubs-datensatz die verknüüfung gemacht wird.
es gibt also zu jedem member mehrere einträge in der tabelle urlaub. wenn ich die beiden verknüpfe muss ich außer dem "urlaub.memberid = member.id" noch eine regelung einfügen, wie die ursprüngliche urlaubs-tabelle sortiert wird.
hoffe ihr versteht was ich meine face-smile
danke für die hilfe!
Mitglied: 16640
16640 Sep 28, 2005 at 12:09:06 (UTC)
Goto Top
Du unterliegst da einem Denkfehler, glaube ich.

Ein Resultset wird immer erst nach dem Joinen in die entsprechende Sortierung gebracht. Du musst also zunächst mal die Joins definieren, dann definieren, was Du an Daten im Resultset haben willst (WHERE) und schließlich sortieren (ORDER BY). Das ganze kannst Du dann noch einschränken mit Schlüsselworten wie DISTINCT oder TOP.

Wir bauen ein Beispiel:

create table member
    (   
        memberid     int,
        name         varchar(50) 
    )

create table urlaub
    (
        memberid        int,
        beginn          datetime,
        ende            datetime
    )

Wenn wir jetzt einfach die beiden Tabellen joinen

select * from member m inner join urlaub u on m.memberid = u.memberid

erhalten wir ein Resultset, in dem zu jedem Member die einzelnen Records in der Tabelle urlaub aufgeführt sind. Das können wir jetzt sortieren, bspw.:

select * 
   from member m 
   inner join urlaub u 
   on m.memberid = u.memberid 
   order by m.memberid, u.beginn

Deine Aussage zur Verwednung des group by und daraus resultierenden einzelnen Ergebnissatzes ist nicht richtig. Bei Dir kommen da sicher noch andere Umstände ins Spiel, die das Ergebnis fälschlicherweise als fast richtig aussehen lassen.

Ich komm' nochmal auf meine Frage zurück: Was soll Dir das Resultset als Ergebnis liefern?

dba
Mitglied: 5322
5322 Sep 28, 2005 at 12:36:30 (UTC)
Goto Top
ok, nimm mal bitte das folgende sql und importiere es in eine db:
(urlaubid hattest du nicht, benötige ich aber...)

CREATE TABLE `member` (
  `memberid` int(11) default NULL,
  `name` varchar(50) default NULL
) TYPE=MyISAM;

INSERT INTO `member` (`memberid`, `name`) VALUES (1, 'richard');  
INSERT INTO `member` (`memberid`, `name`) VALUES (2, 'erich');  
INSERT INTO `member` (`memberid`, `name`) VALUES (3, 'peter');  

CREATE TABLE `urlaub` (
  `urlaubid` int(11) default NULL,
  `memberid` int(11) default NULL,
  `beginn` datetime default NULL,
  `ende` datetime default NULL
) TYPE=MyISAM;

INSERT INTO `urlaub` (`urlaubid`, `memberid`, `beginn`, `ende`) VALUES (1, 1, '2005-01-01 00:12:00', '2005-02-01 00:12:00');  
INSERT INTO `urlaub` (`urlaubid`, `memberid`, `beginn`, `ende`) VALUES (2, 2, '2005-03-01 00:12:00', '2005-03-02 00:12:00');  
INSERT INTO `urlaub` (`urlaubid`, `memberid`, `beginn`, `ende`) VALUES (3, 3, '2005-10-01 00:12:00', '2005-11-11 00:12:00');  
INSERT INTO `urlaub` (`urlaubid`, `memberid`, `beginn`, `ende`) VALUES (5, 3, '2007-10-01 00:12:00', '2007-11-11 00:12:00');  
INSERT INTO `urlaub` (`urlaubid`, `memberid`, `beginn`, `ende`) VALUES (4, 3, '2006-10-01 00:12:00', '2006-11-11 00:12:00');  

folgendes gibt mir alle datensätze verknüpft aus:
select * from member m inner join urlaub u on m.memberid = u.memberid

mit folgendem statement bekomme ich in etwa die zeilen, wie ich sie später benötige:
SELECT  * FROM member m INNER  JOIN urlaub u ON m.memberid = u.memberid GROUP  BY m.memberid

und nun brauch ich hier bspw. bei "peter" den am weitesten entfernten urlaub, also im jahr 2007. wie komme ich da ran?? bei mir werden immer nur bei allen drei members die urlaube 2005 angezeigt. da ist nicht drin mit order by oder so, das sortiert mir nämlich nur die bereits fertige tabelle....

besten dank für deine unterstützung!!
Mitglied: 16640
16640 Sep 28, 2005 at 12:58:03 (UTC)
Goto Top
select 
    m.memberid,
    m.name,
    max(u.beginn) as anfang
  from 
    member m 
    inner join urlaub u 
  on m.memberid = u.memberid 
  
  group by 
    m.memberid,
    m.name
    

Meinst Du so?
Mitglied: 5322
5322 Sep 28, 2005 at 13:03:58 (UTC)
Goto Top
hey,
spitze!
aber jetzt kommts (so langsam wirds speziell face-smile ):
füge mal bei deinem select noch "u.ende" hinzu. und jetzt müsste auch das passende urlaubs-end-datum herauskommen, mach es aber nicht... u.ende müsste sich irgendwie auf u.anfang beziehen.
wie kann ich das machen?
Mitglied: 16640
16640 Sep 28, 2005 at 13:19:41 (UTC)
Goto Top
Probier das face-wink

select 
    hlp.mid,
    hlp.nam,
    u.beginn,
    u.ende
from
    (
        select 
            mem.memberid mid,
            mem.name     nam,
            max(url.beginn) as anf
        from 
            member mem 
            inner join urlaub url
        on mem.memberid = url.memberid 
        group by 
            mem.memberid,
            mem.name
    ) as hlp 
    inner join urlaub u
    on u.beginn = hlp.anf
Mitglied: 5322
5322 Sep 28, 2005 at 13:24:31 (UTC)
Goto Top
#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 'SELECT mem.memberid mid, mem.name nam, max( url.beginn )  AS an  
face-sad
evtl. weil ich nur MySQL 4.0.20 hab?
Mitglied: 16640
16640 Sep 28, 2005 at 13:30:43 (UTC)
Goto Top
DAS kann ich Dir nicht beantworten. Vielleicht kommen da auch Unterschiede zwischen MySQL und dem SQL Server, den ich hier verwende, zum Vorschein. Ich hab' nochmal den Code aus meinem Posting importiert und laufen lassen, um Übertragunssfehler auszuschliessen. Als Ergebnis bekomme ich das hier:

mid nam beginn ende
1 richard 2005-01-01 00:12:00.000 2005-01-02 00:12:00.000
2 erich 2005-01-03 00:12:00.000 2005-02-03 00:12:00.000
3 peter 2007-01-10 00:12:00.000 2007-11-11 00:12:00.000

Sieht doch eigentlich gut aus. Was die Fehlermeldung jetzt bei Dir verursacht, müsstest Du mal herausfinden und dann einen Workaround für bauen.

Vielleicht stoert er sich an 'url' oder 'mem' als Alias? Ändere doch mal in u2 und m2, die beiden. Mehr fällt mir dazu jetzt nicht ein.

sorry, dba
Mitglied: 5322
5322 Sep 28, 2005 at 13:51:11 (UTC)
Goto Top
hi,
also am alias liegt es nicht. subselects werden bei mysql erst ab version 4.1 unterstützt und selbstverständlich kann ich nicht so einfach updaten face-sad face-sad
gibt es hierfür evtl. noch ein workaround?
Mitglied: 16640
16640 Sep 28, 2005 at 13:54:03 (UTC)
Goto Top
Dann mach's in zwei Schritten, den Subselect in eine Hilfstabelle [insert into...] und danach dann den eigentlichen Select mit dem Join auf die Hilfstabelle.

Das sollte doch funktionieren.

Ansonsten bin ich gleich erstmal weg ,-)

dba