levu: Komplexe Abfrabe bezgl. "Neighbours" (MySql 5)

Hallo,

ich möchte ein kleines Spiel schreiben, da gibt es eine Landkarte, die ist in Felder eingeteilt, die mit x und y angesprochen werden.

Wenn jetzt ein Benutzer einen neuen Account anlegt, bekommt er ein plusförmiges Gebiet auf der Karte:

+-------+
        | x|y-1 |
        |       |
+-------+-------+-------+

x-1|y | x|y   | x+1|y |
      |       |       |

+-------+-------+-------+
        | x|y+1 |
        |       |
        +-------+

Wobei x und y die Mitte dieses Kreuzes bezeichnen. Nun möchte ich die kleinsten x und y ( MIN(x+y) ) bekommen, bei denen die vier anderen Felder noch nich in der Datenbank vorkommen. Die Spalten heißen x und y und ich vermute, dass man das über eine Subquery machen muss, hab davon aber keine Ahnung :|.

Ich hoffe, ihr könnt mir immerhin einige Ansätze geben!

mfg, Flo

--
sh:) fo:| ch:? rl:( br:^ n4:| ie:{ mo:| va:} de:> zu:} fl:{ ss:) ls:< js:|
  1. Hallo,

    Sorry, ich möchte nicht des Crosspostings beschuldigt werden, aber ich habe diese Frage wegen Zeitdruck jetzt auch noch auf entwickler-forum.de gestellt :(

    mfg, Flo

    --
    sh:) fo:| ch:? rl:( br:^ n4:| ie:{ mo:| va:} de:> zu:} fl:{ ss:) ls:< js:|
  2. Hallo,

    dein Problem ist nicht ganz rübergekommen ...

    Wenn jetzt ein Benutzer einen neuen Account anlegt, bekommt er ein plusförmiges Gebiet auf der Karte:

    Abhängig von was? Von seinem Wohnort? Also hat die Karte Koordinaten? Und die Mitte des Kreuzes liegt etwa auf 8,1° Ost und 51,2° Nord?

    Wobei x und y die Mitte dieses Kreuzes bezeichnen.

    Okay, x=8,1 y=51,2 Wie fein ist das Raster? Auf eine Stelle hinter dem Komma genau? Dann hast du die Nachbarfelder oben: x=8,1 y=51,3 / links: x=8,0 y=51,2 / rechts: x=8,3 y=51,2 / unten: x=8,1 y=51,1

    Nun möchte ich die kleinsten x und y ( MIN(x+y) ) bekommen, bei denen die vier anderen Felder noch nich in der Datenbank vorkommen.

    Das wäre in dem Beispiel immer in Afrika, nahe 0° 0°.

    Aber ich denke, dein Koordinatensystem ist irgendwie anders gedacht.

    LG Kalle

    1. Hallo,

      dein Problem ist nicht ganz rübergekommen ...

      Ich bin von etwas gesundem Menschenverstand ausgegangen, aber ich hab mich vielleicht auch nicht ganz genau ausgedrückt :)

      Wenn jetzt ein Benutzer einen neuen Account anlegt, bekommt er ein plusförmiges Gebiet auf der Karte:

      Abhängig von was? Von seinem Wohnort? Also hat die Karte Koordinaten?

      Genau, die Mitte ist z.B. 0|0, muss aber nicht

      Und die Mitte des Kreuzes liegt etwa auf 8,1° Ost und 51,2° Nord?

      Vom Zufall

      Wobei x und y die Mitte dieses Kreuzes bezeichnen.

      Okay, x=8,1 y=51,2 Wie fein ist das Raster? Auf eine Stelle hinter dem Komma genau? Dann hast du die Nachbarfelder oben: x=8,1 y=51,3 / links: x=8,0 y=51,2 / rechts: x=8,3 y=51,2 / unten: x=8,1 y=51,1

      Keine Nachkommastelle :)

      Nun möchte ich die kleinsten x und y ( MIN(x+y) ) bekommen, bei denen die vier anderen Felder noch nich in der Datenbank vorkommen.

      Das wäre in dem Beispiel immer in Afrika, nahe 0° 0°.

      Wenn aber dort schon welche sind, dann ist es weiter weg, weil nicht 2 am gleichen Ort sein können!

      mfg, Flo

      --
      sh:) fo:| ch:? rl:( br:^ n4:| ie:{ mo:| va:} de:> zu:} fl:{ ss:) ls:< js:|
      1. Okay,

        du suchst also ein Rechteck B2, denen die Nachbarn A2, B1, B3 und C2 fehlen.

        1      2      3
          +------+------+-----+
        A |  A1  |  A2  |  A3  |
          +------+------+-----+
        B |  B1  |  B2  |  B3  |
          +------+------+-----+
        C |  C1  |  C2  |  C3  |
          +------+------+-----+

        Aber mir ist immer noch nicht klar, wie die x|y Werte der Rechtecke hinterlegt sind. Davon hängt ja die Datenbankabfrage ab.

        Abhängig von was? Von seinem Wohnort? Also hat die Karte Koordinaten?
        Genau, die Mitte ist z.B. 0|0, muss aber nicht

        Du musst dich entscheiden, sonst weisst du nicht, nach was du fragen sollst.

        Grundsätzliche Idee: Du selektierst alle Rechtecke und packst per JOIN die vier gefragten Nachbarn dazu (genau jetzt brauchst du die Koordinaten). Alle Rechtecke, die mit viermal NULL übrig bleiben, kommen in die engere Wahl.

        Und nun musst du das mit den kleinsten Koordinaten bestimmen.

        Kalle

        1. Hallo,

          Aber mir ist immer noch nicht klar, wie die x|y Werte der Rechtecke hinterlegt sind. Davon hängt ja die Datenbankabfrage ab.

          Das ist der springende Punkt: die sollen dynamisch ermittelt werden, und zwar so, dass x+y minimiert wird. pseudosprache:

          für alle x und y denen die vier nachbarfelder fehlen, gib mir das zurück, welches am nächsten am Punkt (a|b) z.B. (0|0) liegt!

          mfg, Flo

          --
          sh:) fo:| ch:? rl:( br:^ n4:| ie:{ mo:| va:} de:> zu:} fl:{ ss:) ls:< js:|
          1. Hallo,

            Das ist der springende Punkt: die sollen dynamisch ermittelt werden

            Kannst du mal definieren, wie du der Datenbank mitteilst, was "Nachbarfelder" sind?

            Kalle

            1. Hallo,

              Kannst du mal definieren, wie du der Datenbank mitteilst, was "Nachbarfelder" sind?

              Das war meine Frage!!

              mfg, Flo

              --
              sh:) fo:| ch:? rl:( br:^ n4:| ie:{ mo:| va:} de:> zu:} fl:{ ss:) ls:< js:|
          2. für alle x und y denen die vier nachbarfelder fehlen, gib mir das zurück, welches am nächsten am Punkt (a|b) z.B. (0|0) liegt!

            Das ist jetzt ganz was anderes. Dein Ursprungsproblem war:

            Nun möchte ich die kleinsten x und y ( MIN(x+y) ) bekommen, bei denen die vier anderen Felder noch nich in der Datenbank vorkommen.

            Jetzt geht es aber offensichtlich um die Entfernung zu einem variabel gesetzten Rechteck B2.

            Die Aufgabe muss schon klar sein, wenn man Rat bekommen möchte.

            Kalle

            1. Hallo,

              für alle x und y denen die vier nachbarfelder fehlen, gib mir das zurück, welches am nächsten am Punkt (a|b) z.B. (0|0) liegt!

              Das ist jetzt ganz was anderes. Dein Ursprungsproblem war:

              nicht unbedingt:

              Nun möchte ich die kleinsten x und y ( MIN(x+y) ) bekommen, bei denen die vier anderen Felder noch nich in der Datenbank vorkommen.

              Jetzt geht es aber offensichtlich um die Entfernung zu einem variabel gesetzten Rechteck B2.

              genau, der kann 0|0 sein, ich nenne seine Koordinaten mal a und b, dann lautet der Ausdruck nun so:
              MIN ((x - a) + (y - b)), bei a und b gleich 0, ist es eben MIN (x + y)
              Ich hoffe, das reicht diesmal :)

              Die Aufgabe muss schon klar sein, wenn man Rat bekommen möchte.

              Ich hätte mich klarer ausdrücken sollen :)

              mfg, Flo

              --
              sh:) fo:| ch:? rl:( br:^ n4:| ie:{ mo:| va:} de:> zu:} fl:{ ss:) ls:< js:|
  3. Hallo,

    Wie kann ich mir denn den X-Wert (INT, > 0) zurückgeben lassen, der am kleinsten ist, von denen, die NICHT in der datenbank vorkommen. Muss ich mir die geordnet ausgeben lassen und prüfen, wenn einer nicht dabei ist, oder kann ich das per SQL machen?

    Das würde mir schon reichen, den Rest kann ich, nach etwas überlegen, nun doch irgendwie hindrehen :)

    mfg, Flo

    --
    sh:) fo:| ch:? rl:( br:^ n4:| ie:{ mo:| va:} de:> zu:} fl:{ ss:) ls:< js:|
    1. Hello,

      Wie kann ich mir denn den X-Wert (INT, > 0) zurückgeben lassen, der am kleinsten ist, von denen, die NICHT in der datenbank vorkommen.

      solange du wirklich nur den X-Wert brauchst, kann man da was mäßig performantes bauen:

        
      SELECT xwert+1  
      FROM tabelle tselect  
      WHERE NOT EXISTS (SELECT xwert FROM tabelle tsubselect WHERE tsubselect.xwert = (tselect.xwert+1))  
      
      

      Dieses Statement sucht (hoffe ich) zunächst mal alle Werte, die einen unmittelbaren Vorgänger haben, aber nicht selbst in der Tabelle vorkommen.

      Von diesen Werten suchst du nun den kleinsten, also entweder MIN(...) oder ein ORDER BY mit LIMIT.

      MfG
      Rouven

      --
      -------------------
      sh:| fo:} ch:? rl:( br:& n4:{ ie:| mo:} va:) js:| de:] zu:| fl:( ss:) ls:& (SelfCode)
      Death is nature's way of telling you to slow down.
      1. Hallo,

        Also praktisch:

          
        SELECT `x`+1  
        FROM `regions` tselect  
        WHERE NOT EXISTS (SELECT `x` FROM `regions` tsubselect WHERE tsubselect.xwert = (tselect.xwert+1)) ORDER BY `x` ASC LIMIT 1  
        
        

        oder hab ich das mit dem "tabelle" falsch verstanden?

        mfg, Flo

        --
        sh:) fo:| ch:? rl:( br:^ n4:| ie:{ mo:| va:} de:> zu:} fl:{ ss:) ls:< js:|
    2. Hi,

      Wie kann ich mir denn den X-Wert (INT, > 0) zurückgeben lassen, der am kleinsten ist, von denen, die NICHT in der datenbank vorkommen.

      Ziehe vom minimalen X-Wert (eingeschränkt auf die X-Werte größer 1) 1 ab.

      cu,
      Andreas

      --
      Warum nennt sich Andreas hier MudGuard?
      O o ostern ...
      Fachfragen unaufgefordert per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
      1. Hello,

        Ziehe vom minimalen X-Wert (eingeschränkt auf die X-Werte größer 1) 1 ab.

        klingt wie eine interessante Idee, aber was ist mit
        1 2 _ 4 5 _ 7

        Gesucht wäre 3

        MfG
        Rouven

        --
        -------------------
        sh:| fo:} ch:? rl:( br:& n4:{ ie:| mo:} va:) js:| de:] zu:| fl:( ss:) ls:& (SelfCode)
        Computer programming is tremendous fun. Like music, it is a skill that derives from an unknown blend of innate talent and constant practice. Like drawing, it can be shaped to a variety of ends: commercial, artistic, and pure entertainment. Programmers have a well-deserved reputation for working long hours but are rarely credited with being driven by creative fevers. Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination, but because their imagination reveals worlds that others cannot see. -- Larry OBrien and Bruce Eckel in Thinking in C#