Announcement

Collapse
No announcement yet.

Zu einem Datensatz nur x Datensätze auslesen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Zu einem Datensatz nur x Datensätze auslesen

    Hi,

    irgendwie finde ich einfach nichts zu meinem Problem.. welches aber irgendwie simpel ist...

    Ich habe zwei Tabellen. Einmal postings und einmal comments. Die comments Einträge sind über die posting ID mit den postings verbunden.

    Jetzt möchte ich zu jedem Posting die letzten drei comments auslesen. Leider kann man aber bei einem LEFT JOIN kein LIMIT setzen und ich finde einfach keine vernünftige Lösung wie ich das sonst machen kann, außer über mehrere Abfragen...

    Hat da jemand eine Idee zu?

    Danke für die Antworten im voraus
    Flare
    Zuletzt editiert von flare; 13.09.2012, 19:22.

  • #2
    vielleicht so:
    Code:
    Select * from ([Eigentliches Selectstatement order by letztezuerst]) limit 3
    Gruß, defo

    Comment


    • #3
      Hi, das wäre zu einfach und ich habe es etwas anders beschrieben.

      Beispiel: Ich habe eine Liste in der DB die z.b. wie folgt aussieht:

      Code:
      Postings
      post_id   title
      1         cccccc
      2         cccccc
      3         cccccc
      4         cccccc
      
      Comments
      comment_id    post_id    text...
      1               1         xxxxxxxxxxx
      2               1         xxxxxxxxxxx
      3               2         xxxxxxxxxxx
      4               2         xxxxxxxxxxx
      5               3         xxxxxxxxxxx
      6               3         xxxxxxxxxxx
      7               3         xxxxxxxxxxx
      8               3         xxxxxxxxxxx
      9               3         xxxxxxxxxxx
      
      SELECT * FROM postings LEFT JOIN comments ON comments.post_id = postings.post_id
      Damit kriegst du zu jedem posting die comments. Und hier sollen nur maximal 3 neue posts pro posting selektiert werden.
      Zuletzt editiert von flare; 13.09.2012, 23:07.

      Comment


      • #4
        Originally posted by flare View Post
        Hi, das wäre zu einfach und ich habe es etwas anders beschrieben.

        Beispiel: Ich habe eine Liste in der DB die z.b. wie folgt aussieht:

        Code:
        Postings
        post_id   title
        1         cccccc
        2         cccccc
        3         cccccc
        4         cccccc
        
        Comments
        comment_id    post_id    text...
        1               1         xxxxxxxxxxx
        2               1         xxxxxxxxxxx
        3               2         xxxxxxxxxxx
        4               2         xxxxxxxxxxx
        5               3         xxxxxxxxxxx
        6               3         xxxxxxxxxxx
        7               3         xxxxxxxxxxx
        8               3         xxxxxxxxxxx
        9               3         xxxxxxxxxxx
        
        SELECT * FROM postings LEFT JOIN comments ON comments.post_id = postings.post_id
        Damit kriegst du zu jedem posting die comments. Und hier sollen nur maximal 3 neue posts pro posting selektiert werden.

        Du hast also:

        Code:
        test=*# select * from postings ;
         id | title
        ----+-------
          1 | post1
          2 | post2
          3 | post3
          4 | post4
        (4 rows)
        
        test=*# select * from comments ;
         id | post_id |     t
        ----+---------+-----------
          1 |       1 | comment1
          2 |       1 | comment2
          3 |       2 | comment3
          4 |       3 | comment4
          5 |       1 | comment5
          6 |       1 | comment6
          7 |       2 | comment7
          8 |       2 | comment8
          9 |       1 | comment9
         10 |       2 | comment10
        (10 rows)
        
        test=*# select * from postings left join comments on comments.post_id=postings.id;
         id | title | id | post_id |     t
        ----+-------+----+---------+-----------
          1 | post1 |  1 |       1 | comment1
          1 | post1 |  2 |       1 | comment2
          1 | post1 |  5 |       1 | comment5
          1 | post1 |  6 |       1 | comment6
          1 | post1 |  9 |       1 | comment9
          2 | post2 | 10 |       2 | comment10
          2 | post2 |  7 |       2 | comment7
          2 | post2 |  3 |       2 | comment3
          2 | post2 |  8 |       2 | comment8
          3 | post3 |  4 |       3 | comment4
          4 | post4 |    |         |
        (11 rows)
        Für das, was Du willst, bräuchtest Du eine Funktion, die es in MySQL nicht gibt: row_number(). Damit ginge das dann so:

        Code:
        test=*# select * from (select *, row_number() over (partition by postings.id) from postings left join comments on comments.post_id=postings.id) foo where row_number <=3;
         id | title | id | post_id |     t     | row_number
        ----+-------+----+---------+-----------+------------
          1 | post1 |  1 |       1 | comment1  |          1
          1 | post1 |  2 |       1 | comment2  |          2
          1 | post1 |  5 |       1 | comment5  |          3
          2 | post2 | 10 |       2 | comment10 |          1
          2 | post2 |  7 |       2 | comment7  |          2
          2 | post2 |  3 |       2 | comment3  |          3
          3 | post3 |  4 |       3 | comment4  |          1
          4 | post4 |    |         |           |          1
        (8 rows)
        Irgendwo in den Tiefen des WWW fand ich mal eine Frickellösung für MySQL, die row_number() simuliert, vielleicht findest Du das ja.


        Andreas
        Zuletzt editiert von akretschmer; 16.09.2012, 08:50. Reason: copy@paste-fehler beseitigt

        Comment


        • #5
          Originally posted by flare View Post
          Hi, das wäre zu einfach und ich habe es etwas anders beschrieben.
          Ja, ok, das war witzlos für eine PID.

          Besser so?
          Code:
          Field | Type
          --------------------
          cid   | int(11)
          pid   | int(11)
          text  | varchar(20)
          [Highlight=SQL]
          SELECT t.*,
          @prev,
          @rownum := CASE pid
          WHEN @prev THEN @rownum + 1
          ELSE 1
          end AS rownumber,
          @prev := t.pid
          FROM (SELECT *
          FROM comments
          ORDER BY pid, cid) t,
          (SELECT @rownum := 0,
          @prev := 0) r;
          [/Highlight]

          @akretschmer
          Ich finde die Variablen in mysql eigentlich recht elegant, wniger frickelig.

          P.S: Die comments müssen natürlich andersrum sortiert werden.
          Zuletzt editiert von defo; 14.09.2012, 08:47.
          Gruß, defo

          Comment


          • #6
            Originally posted by defo View Post
            @akretschmer
            Ich finde die Variablen in mysql eigentlich recht elegant, wniger frickelig.
            IIRC kennt SQL keine Variablen, row_number() aber sehr wohl. Aber wenn es so wie von Dir gezeigt geht reicht das ja dem Fragesteller...

            Andreas

            Comment


            • #7
              Ja das mit row_number hab ich auch schonmal gesehen, aber mysql kann das ja leider nicht.

              @defo deine Lösung sieht komplex aber gefühlsmäßig richtig aus.. nur blick ich da nicht durch und sehe nicht, dass dort auch die posting Daten mitgelesen werden. Könntest du die vielleicht einwenig erklären? Wäre nett.

              Comment


              • #8
                Originally posted by flare View Post
                Ja das mit row_number hab ich auch schonmal gesehen, aber mysql kann das ja leider nicht.

                @defo deine Lösung sieht komplex aber gefühlsmäßig richtig aus.. nur blick ich da nicht durch und sehe nicht, dass dort auch die posting Daten mitgelesen werden. Könntest du die vielleicht einwenig erklären? Wäre nett.
                Die 'pid' soll die Posting ID sein, die Tabelle postings kannst Du darüber reinjoinen.
                Soweit ich weiß, gibt's Variablen auch nur bei mysql, mit Ihrer Hilfe bildet man die RowNumber() Funktion nach, in diesem Fall eher eine SubRowNumber, weil bei jeder neuen PID (Sortierfolge wichtig!) wieder mit 1 begonnen wird. Der Neustart bei 1, bzw. seine Detektierung erfolgt über @prev, die nichts anderes macht, als den PID Wechsel nachzuvollziehen und dann @rownum auf 0 setzt.
                Mein Beispiel wirft nur die Gesamtmenge der Comments aus. Muss noch auf rownumber <4 gefiltert und mit postings gejoined werden.
                Gruß, defo

                Comment

                Working...
                X