n Einträge pro Gruppe

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Zeige mir alle Benutzer und ihre letzten 2 Einkäufe. Einfache Anforderung, oder? Die Abfrage dazu ist um so komplexer.
    == Problemstellung ==
    Es gibt die Tabelle User (Benutzer), die Tabelle Items (Artikel) und sie werden über die Tabelle Sales (Einkäufe) miteinander verknüpft, sobald der Benutzer einen Artikel kauft.
    easy-coding.de/Attachment/489/…b434116caca47e1791a8678f6

    == Abfrage aller Einkäufe ==

    Quellcode

    1. SELECT userid,itemid,date FROM `sales` WHERE userid IN (1,3,5);

    Brainfuck-Quellcode

    1. +--------+--------+------------+
    2. | userid | itemid | date |
    3. +--------+--------+------------+
    4. | 1 | 915 | 2005-08-17 |
    5. | 1 | 2442 | 2004-04-14 |
    6. | 1 | 3321 | 2005-09-27 |
    7. | 1 | 4326 | 2005-10-29 |
    8. | 1 | 11589 | 2005-10-19 |
    9. | 1 | 13651 | 2004-06-16 |
    10. | 1 | 14756 | 2005-12-27 |
    11. | 1 | 14924 | 2005-10-04 |
    12. | 1 | 16272 | 2005-01-20 |
    13. | 1 | 21722 | 2005-02-07 |
    14. | 1 | 30245 | 2004-10-19 |
    15. | 1 | 31913 | 2004-10-15 |
    16. | 1 | 34907 | 2005-08-17 |
    17. | 1 | 38052 | 2004-06-03 |
    18. | 1 | 42921 | 2005-10-04 |
    19. | 1 | 42930 | 2005-05-14 |
    20. | 3 | 1333 | 2004-05-18 |
    21. | 3 | 3417 | 2005-09-27 |
    22. | 3 | 3718 | 2004-02-09 |
    23. | 3 | 4783 | 2003-04-25 |
    24. | 3 | 5225 | 2005-07-07 |
    25. | 3 | 6384 | 2003-08-26 |
    26. | 3 | 6460 | 2003-10-07 |
    27. | 3 | 6510 | 2004-09-13 |
    28. | 3 | 6689 | 2003-02-20 |
    29. | 3 | 10251 | 2004-06-02 |
    30. | 3 | 10996 | 2003-11-28 |
    31. | 3 | 14035 | 2005-10-12 |
    32. | 3 | 15420 | 2004-03-29 |
    33. | 3 | 16229 | 2005-11-09 |
    34. | 3 | 16272 | 2003-02-13 |
    35. | 3 | 16818 | 2004-02-23 |
    36. | 3 | 21296 | 2003-09-04 |
    37. | 3 | 21777 | 2003-08-28 |
    38. | 3 | 21983 | 2003-04-19 |
    39. | 3 | 22853 | 2004-02-10 |
    40. | 3 | 23174 | 2003-03-07 |
    41. | 3 | 24344 | 2004-08-20 |
    42. | 3 | 25049 | 2004-05-17 |
    43. | 3 | 27061 | 2004-10-14 |
    44. | 3 | 28995 | 2005-06-30 |
    45. | 3 | 29948 | 2003-12-21 |
    46. | 3 | 32555 | 2003-12-15 |
    47. | 3 | 32902 | 2004-01-16 |
    48. | 3 | 33849 | 2005-07-11 |
    49. | 3 | 35770 | 2004-12-28 |
    50. | 3 | 37939 | 2005-07-11 |
    51. | 3 | 38129 | 2005-02-07 |
    52. | 3 | 40112 | 2003-03-16 |
    53. | 3 | 41371 | 2004-01-21 |
    54. | 3 | 41947 | 2003-10-04 |
    55. | 5 | 685 | 2005-11-30 |
    56. | 5 | 3321 | 2005-09-09 |
    57. | 5 | 8117 | 2005-11-13 |
    58. | 5 | 11186 | 2005-03-13 |
    59. | 5 | 13432 | 2005-05-08 |
    60. | 5 | 17063 | 2005-03-01 |
    61. | 5 | 19006 | 2005-03-22 |
    62. | 5 | 19289 | 2005-02-17 |
    63. | 5 | 21153 | 2005-10-03 |
    64. | 5 | 23948 | 2005-11-15 |
    65. | 5 | 29350 | 2005-02-24 |
    66. | 5 | 31361 | 2005-08-24 |
    67. | 5 | 33256 | 2004-11-29 |
    68. | 5 | 36818 | 2005-02-01 |
    69. | 5 | 39526 | 2005-01-20 |
    70. +--------+--------+------------+
    Alles anzeigen


    == Abfrage der Benutzer mit 'einem' Einkauf ==
    Gruppieren wir die erste Abfrage nach der userid erhalten wir alle Benutzer mit dem Artikel und dem Datum des ersten Einkaufs bzw der natürlichen Reihenfolge, die sich durch das Einfügen in die Tabelle erschließt.
    Da diese natürliche Reihenfolge durch den Befehl OPTIMIZE TABLE wieder durcheinander gebracht wird, kann man aber eigentlich nur von einem beliebigem Einkauf reden, der angezeigt wird.

    Quellcode

    1. SELECT userid,itemid,date FROM `sales` WHERE userid IN (1,3,5) GROUP BY userid;

    Brainfuck-Quellcode

    1. +--------+--------+------------+
    2. | userid | itemid | date |
    3. +--------+--------+------------+
    4. | 1 | 915 | 2005-08-17 |
    5. | 3 | 1333 | 2004-05-18 |
    6. | 5 | 685 | 2005-11-30 |
    7. +--------+--------+------------+


    == Abfrage der Benutzer mit ihrem letzten Einkauf ==
    Wollen wir statt dem ersten Einkauf den letzten erhalten, dann müssen wir die natürliche Reihenfolge, nach der MySQL gruppiert umdrehen, indem wir die Abfrage in einem Subselect absteigend nach der Zeit sortieren.

    Quellcode

    1. SELECT userid,itemid,date FROM (
    2. SELECT * FROM sales ORDER BY date DESC
    3. ) sales WHERE userid IN (1,3,5);

    Brainfuck-Quellcode

    1. +--------+--------+------------+
    2. | userid | itemid | date |
    3. +--------+--------+------------+
    4. | 1 | 14756 | 2005-12-27 |
    5. | 3 | 16229 | 2005-11-09 |
    6. | 5 | 685 | 2005-11-30 |
    7. +--------+--------+------------+


    == Lösung ==
    Um nun überhaupt an zwei Artikel zu gelangen, könnte man die letzten beiden Abfragen per UNION verbinden. Doch wir wollen die beiden letzten.
    Dazu bedienen wir uns zweier MySQL Variablen. @x und @userid_tmp.
    @x ist eine Zählervariable. Sie nummeriert alle gekauften Items eines Benutzers durch. Sobald @userid_tmp nicht mehr der aktuellen userid ist, dann wird der Zähler zurück gesetzt und die Nummerierung beginnt beim nächsten Benutzer.
    Wenn wir die letzten beiden Käufe erhalten wollen, brauchen wir In der WHERE Bedingung nur noch auf die Käufe mit den Zahlen 1 und 2 einzuschränken.

    Quellcode

    1. SET @x = 0;
    2. SET @userid_tmp = 0;
    3. SELECT userid,itemid,date FROM (
    4. SELECT userid,itemid,date,
    5. @x := IF(@userid_tmp = userid, @x+1, 0) AS c,
    6. @userid_tmp := userid AS d
    7. FROM `sales` WHERE userid IN (1,3,5,6,10,12)
    8. ORDER BY userid ASC,date DESC
    9. ) sub
    10. WHERE c < 2;
    Alles anzeigen

    Brainfuck-Quellcode

    1. +--------+--------+------------+------+----+
    2. | userid | itemid | date | c | d |
    3. +--------+--------+------------+------+----+
    4. | 1 | 915 | 2005-08-17 | 0 | 1 |
    5. | 1 | 2442 | 2004-04-14 | 1 | 1 |
    6. | 3 | 1333 | 2004-05-18 | 0 | 3 |
    7. | 3 | 3417 | 2005-09-27 | 1 | 3 |
    8. | 5 | 685 | 2005-11-30 | 0 | 5 |
    9. | 5 | 3321 | 2005-09-09 | 1 | 5 |
    10. +--------+--------+------------+------+----+
    Bilder
    • user-sale-item.png

      4,78 kB, 345×180, 591 mal angesehen

    8.673 mal gelesen