"freie Autos" filtern

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

  • "freie Autos" filtern

    Hallo beisammen,

    ich habe folgende DB Struktur:

    Kunde(kid,name,telefon)
    Autos(aid,typ,klimanlage, freisprech)
    Buchen(id, kid,aid,von,bis)

    Nun würde ich gerne gucken, ob irgendein Auto mit den gewünschten Kriterien (zb klimaanlage = true, freisprech = false) zu einem bestimmten Zeitpunkt frei ist.
    Also von wegen: "liste mir alle Autos, welche eine Klimaanlage und keine Freisprecheinrichtung haben und vom 01.01.2009 bis zum 15.01.2009 frei sind".
    Mein Problem ist, dass ich nicht weiß, wie ich die beiden Daten kombiniere. Eigentlich doch sowas "von<=01.01.2009 and bis>=15.01.2009", oder?


    Danke
  • Alles was komplett außerhalb der angegebenenen Zeitspanne ist, ist gut für uns

    Quellcode

    1. # linker rand
    2. von < 01.01.2009
    3. AND bis < 01.01.2009


    OR

    Quellcode

    1. # rechter rand
    2. von > 19.01.2009
    3. AND bis > 19.01.2009



    und wenn das Auto noch nie ausgliehen wurde, ist natürlich auch super (left join mit isnull)

    d.h. das Ergebnis wird in etwa so aussehen:

    Quellcode

    1. SELECT * FROM Autos
    2. LEFT JOIN Buchen ON Autos.aid = Buchen.aid
    3. WHERE
    4. Autos.klimaanlage = 1
    5. AND
    6. ISNULL(Buchen.aid)
    7. OR
    8. (von < 01.01.2009
    9. AND bis < 01.01.2009)
    10. OR
    11. (von > 19.01.2009
    12. AND bis > 19.01.2009)
    Alles anzeigen
  • Hallo beisammen,

    eine Frage hätte ich allerdings doch noch,
    an sich funktioniert die Abfrage ja, allerdings werden zuerst alles Buchungen angezeigt, bevor das eigentlich Ergebnis kommt.

    Kriegen wir die da irgendwie raus?
    siehe Beispiel:

    SQL-Abfrage

    1. SELECT * FROM autos LEFT JOIN buchen ON autos.aid = buchen.aid WHERE autos.klima = 1 AND ISNULL(buchen.aid) OR (von < '2009-01-01' AND bis < '2009-01-01') OR (von > '2009-01-25' AND bis > '2009-01-25');
    2. +------------+--------+---------+------+----------+-------+------+------------+--------+------------+------------+
    3. | iad | art | klima | ID | aid | GastID | von | bis |
    4. +------------+--------+---------+------+----------+-------+------+------------+--------+------------+------------+
    5. | 1 | cabrio |1 | 11 | 1 | 1 | 2009-02-01 | 2009-02-25 |
    6. | 2 | cabrio | 0 | 0 | 10 | 2 | 1 | 2009-02-01 | 2009-02-25 |
    7. | 2 | cabrio | 0 | 7 | 2 | 2 | 2009-08-01 | 2009-09-25 |
    8. | 4 | kombi | 1 | NULL | NULL | NULL | NULL | NULL |
    9. | 8 | kombi | 1 | NULL | NULL | NULL | NULL | NULL |
    10. +------------+--------+---------+------+----------+-------+------+------------+--------+------------+------------+
    11. 5 rows in set (0.00 sec)
    Alles anzeigen


    Wie man sieht sind die ersten drei Zeilen die gebuchten Autos, darunter kommen die freien Autos (nach Kriterien gefiltert).. Wenn ich jetzt zB noch einen weiteren Filter einbaue, zB "art = cabrio", werden die #4 und #8 garnicht erst angezeigt.. wenn ich "art = kombi" setzen, kommen trotzdem die drei oberen Cabrios..


    Hoffe ihr versteht mich!

    Danke!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von kingele ()

  • mh, hab eigentlich alles getestet:

    Quellcode

    1. Ein Parameter + AND
    2. mysql> SELECT * FROM autos LEFT JOIN buchen ON autos.aid = buchen.aid WHERE autos.klima = 1 AND ISNULL(buchen.aid) OR (von < '2009-01-01' AND bis < '2009-01-01') OR (von > '2009-01-25' AND bis > '2009-01-25');+------------+--------+---------+------+----------+-------+------+------------+--------+------------+------------+
    3. | aid | art |klima | ID | aid | GastID | von | bis |
    4. +------------+--------+---------+------+----------+-------+------+------------+--------+------------+------------+
    5. | 1 | Cabrio |1 | 11 | 1 | 1 | 2009-02-01 | 2009-02-25 |
    6. | 2 | Cabrio |0 | 10 | 2 | 1 | 2009-02-01 | 2009-02-25 |
    7. | 2 | Cabrio |0 | 7 | 2 | 2 | 2009-08-01 | 2009-09-25 |
    8. | 2 | Cabrio |0 | 12 | 2 | 6 | 2009-08-01 | 2009-09-25 |
    9. | 3 | Kombi |1 | NULL | NULL | NULL | NULL | NULL |
    10. | 4 | Kombi |1 | NULL | NULL | NULL | NULL | NULL |
    11. | 5 | Kombi |1 | NULL | NULL | NULL | NULL | NULL |
    12. | 7 | Cabrio |1 | NULL | NULL | NULL | NULL | NULL |
    13. | 8 | Kombi | 1 | NULL | NULL | NULL | NULL | NULL |
    14. | 889 | Kombi | 1 | NULL | NULL | NULL | NULL | NULL |
    15. +------------+--------+---------+------+----------+-------+------+------------+--------+------------+------------+
    16. 10 rows in set (0.00 sec)
    17. 1 argument + OR
    18. mysql> SELECT * FROM autos LEFT JOIN buchen ON autos.aid = buchen.aid WHERE autos.klima = 1 OR ISNULL(buchen.aid) OR (von < '2009-01-01' AND bis < '2009-01-01') OR (von > '2009-01-25' AND bis > '2009-01-25');
    19. +------------+--------+---------+------+----------+-------+------+------------+--------+------------+------------+
    20. | aid | art | klima | ID | aid | GastID | von | bis |
    21. +------------+--------+---------+------+----------+-------+------+------------+--------+------------+------------+
    22. | 1 | Cabrio |1 | 11 | 1 | 1 | 2009-02-01 | 2009-02-25 |
    23. | 1 | Cabrio |1 | 8 | 1 | 1 | 2009-01-01 | 2009-01-25 |
    24. | 2 | Cabrio |0 | 10 | 2 | 1 | 2009-02-01 | 2009-02-25 |
    25. | 2 | Cabrio |0 | 7 | 2 | 2 | 2009-08-01 | 2009-09-25 |
    26. | 2 | Cabrio |0 | 12 | 2 | 6 | 2009-08-01 | 2009-09-25 |
    27. | 3 | Kombi | 1 | NULL | NULL | NULL | NULL | NULL |
    28. | 4 | Kombi | 1 | NULL | NULL | NULL | NULL | NULL |
    29. | 5 | Kombi | 1 | NULL | NULL | NULL | NULL | NULL |
    30. | 6 | Kombi | 0 | NULL | NULL | NULL | NULL | NULL |
    31. | 7 | Cabrio |1 | 1 | NULL | NULL | NULL | NULL | NULL |
    32. | 8 | Kombi | 1 | NULL | NULL | NULL | NULL | NULL |
    33. | 889 | Kombi | 1 | NULL | NULL | NULL | NULL | NULL |
    34. +------------+--------+---------+------+----------+-------+------+------------+--------+------------+------------+
    35. 12 rows in set (0.00 sec)
    36. 2 Arguemente + OR
    37. mysql> SELECT * FROM autos LEFT JOIN buchen ON autos.aid = buchen.aid WHERE autos.klima = 1 AND autos.art = 'Kombi' OR ISNULL(buchen.aid) OR (von < '2009-01-01' AND bis < '2009-01-01') OR (von > '2009-01-25' AND bis > '2009-01-25');
    38. +------------+--------+---------+------+----------+-------+------+------------+--------+------------+------------+
    39. | aid | art |klima | ID | aid | GastID | von | bis |
    40. +------------+--------+---------+------+----------+-------+------+------------+--------+------------+------------+
    41. | 1 | Cabrio |1 | 11 | 1 | 1 | 2009-02-01 | 2009-02-25 |
    42. | 2 | Cabrio |0 | 10 | 2 | 1 | 2009-02-01 | 2009-02-25 |
    43. | 2 | Cabrio |0 | 7 | 2 | 2 | 2009-08-01 | 2009-09-25 |
    44. | 2 | Cabrio |0 | 12 | 2 | 6 | 2009-08-01 | 2009-09-25 |
    45. | 3 | Kombi | 1 | NULL | NULL | NULL | NULL | NULL |
    46. | 4 | Kombi | 1 | NULL | NULL | NULL | NULL | NULL |
    47. | 5 | Kombi | 1 | NULL | NULL | NULL | NULL | NULL |
    48. | 6 | Kombi | 0 | NULL | NULL | NULL | NULL | NULL |
    49. | 7 | Cabrio |1 | NULL | NULL | NULL | NULL | NULL |
    50. | 8 | Kombi | 1 | NULL | NULL | NULL | NULL | NULL |
    51. | 889 | Kombi | 1 | NULL | NULL | NULL | NULL | NULL |
    52. +------------+--------+---------+------+----------+-------+------+------------+--------+------------+------------+
    53. 11 rows in set (0.00 sec)
    54. 2 Argumente + AND
    55. mysql> SELECT * FROM autos LEFT JOIN buchen ON autos.aid = buchen.aid WHERE autos.klima = 1 AND autos.art = 'Kombi' AND ISNULL(buchen.aid) OR (von < '2009-01-01' AND bis < '2009-01-01') OR (von > '2009-01-25' AND bis > '2009-01-25');
    56. +------------+--------+---------+------+----------+-------+------+------------+--------+------------+------------+
    57. | aid | art |klima | ID | aid | GastID | von | bis |
    58. +------------+--------+---------+------+----------+-------+------+------------+--------+------------+------------+
    59. | 1 | Cabrio |1 | 11 | 1 | 1 | 2009-02-01 | 2009-02-25 |
    60. | 2 | Cabrio | 0 | 10 | 2 | 1 | 2009-02-01 | 2009-02-25 |
    61. | 2 | Cabrio |0 | 7 | 2 | 2 | 2009-08-01 | 2009-09-25 |
    62. | 2 | Cabrio | 0 | 12 | 2 | 6 | 2009-08-01 | 2009-09-25 |
    63. | 3 | Kombi | 1 | NULL | NULL | NULL | NULL | NULL |
    64. | 4 | Kombi | 1 | NULL | NULL | NULL | NULL | NULL |
    65. | 5 | Kombi | 1 | NULL | NULL | NULL | NULL | NULL |
    66. | 8 | Kombi | 1 | NULL | NULL | NULL | NULL | NULL |
    67. | 889 | Kombi | 1 | NULL | NULL | NULL | NULL | NULL |
    68. +------------+--------+---------+------+----------+-------+------+------------+--------+------------+------------+
    69. 9 rows in set (0.00 sec)
    Alles anzeigen


    Auch hier sieht es so aus, als würde die AND-Version (Vor ISNULL), das richtige Ergebnis liefern.

    Ich hoffe ihr durchblickt das noch, ich nämlich nicht so sehr :D

    Danke
  • Boolsche Algebra ist kompliziert.
    Bau dir doch einfach eine Klammer

    Quellcode

    1. SELECT * .... WHERE (alte bedingungen) AND klima = 1;


    im Klartext

    Quellcode

    1. SELECT * FROM Autos
    2. LEFT JOIN Buchen ON Autos.aid = Buchen.aid
    3. WHERE (
    4. Autos.klimaanlage = 1
    5. AND
    6. ISNULL(Buchen.aid)
    7. OR
    8. (von < 01.01.2009
    9. AND bis < 01.01.2009)
    10. OR
    11. (von > 19.01.2009
    12. AND bis > 19.01.2009)
    13. ) AND klima = 1
    Alles anzeigen
  • ich weiß nicht ob es was hilft, aber ich würde den kompletten "ist frei" teil auch nochmal klammern.

    also so:

    Quellcode

    1. SELECT * FROM Autos
    2. LEFT JOIN Buchen ON Autos.aid = Buchen.aid
    3. WHERE (
    4. Autos.klimaanlage = 1
    5. AND
    6. (
    7. ISNULL(Buchen.aid)
    8. OR
    9. (von < 01.01.2009
    10. AND bis < 01.01.2009)
    11. OR
    12. (von > 19.01.2009
    13. AND bis > 19.01.2009)
    14. )
    15. ) AND klima = 1
    Alles anzeigen

    weil nämlich laut dev.mysql.com/doc/refman/5.0/en/operator-precedence.html hat der AND operator ne höhere priorität als der OR Operator. Wenn man sich jetzt deine Abfrage anschaut, dann würde er also zuerst

    Quellcode

    1. Autos.klimaanlage = 1
    2. AND
    3. ISNULL(Buchen.aid)

    Auswerten und dann den Rest dazuOdern, was ja nicht Sinn der Sache ist
  • @Donut: mein Fehler,sorry. Dachte die ersten beiden wären die aktuellen Buchungen.

    Aber irgendwie scheint die Abfrage willkürlich zu arbeiten. Mal passts, mal nicht. Hier zum Beispiel so ein tolles unpassendes Resultat :)

    Quellcode

    1. SELECT
    2. auto.aid, auto.art, auto.navi, auto.heizung, auto.klima, auto.raucher
    3. FROM
    4. auto LEFT JOIN buchen ON auto.aid = buchen.aid
    5. where
    6. auto.klima='true'
    7. AND
    8. auto.navi='false'
    9. AND
    10. auto.heizung='false'
    11. AND
    12. auto.navi='false'
    13. AND
    14. auto.art='Einzel'
    15. AND
    16. ISNULL(buchen.aid)
    17. OR
    18. (von <'2010-01-01'
    19. AND
    20. bis <'2010-01-01')
    21. OR
    22. (von <'2020-01-01'
    23. AND
    24. bis <'2020-01-01');
    25. +------------+--------+----------+------+-------+---------+
    26. | aid | art | navi |heizung| klima | raucher |
    27. +------------+--------+----------+------+-------+---------+
    28. | 3 | Doppel | 1 | 0 | 1 | 0 |
    29. | 4 | Doppel | 0 | 1 | 1 | 0 |
    30. | 5 | Doppel | 1 | 0 | 1 | 1 |
    31. | 6 | Doppel | 0 | 0 | 0 | 0 |
    32. | 8 | Doppel | 0 | 1 | 1 | 1 |
    33. +------------+--------+----------+------+-------+---------+
    Alles anzeigen



    Ich habe schon mit etlichen Klammerungen gespielt, damit es vielleicht nicht zu Bindungsproblemen kommt.. aber will alles nichts.
  • also das geht schon mal von vorneherein schief:

    Quellcode

    1. auto.klima='true'

    Ich geh mal davon aus, dass du da den boolean Typ (also tinyint(1)) benutzt. Du prüfst hier aber ob dieser gleich ner zeichenkette ist, was immer false liefert.
    richtig:

    Quellcode

    1. auto.klima= 1

    oder

    Quellcode

    1. auto.klima= TRUE


    Und dann hab ich das ganze jetzt mal bei mir ausprobiert und ich bin der festen Überzeugung, dass es ein Klammerproblem ist...
    Bei mir ist es so:
    funktioniert:

    Quellcode

    1. SELECT
    2. *
    3. FROM
    4. auto LEFT JOIN buchen ON auto.aid = buchen.aid
    5. WHERE
    6. auto.klima=1
    7. AND
    8. auto.typ='Kombi'
    9. AND
    10. (
    11. ISNULL(buchen.aid)
    12. OR
    13. (von <'2009-07-02'
    14. AND
    15. bis <'2009-07-02')
    16. OR
    17. (von <'2009-07-03'
    18. AND
    19. bis <'2009-07-03')
    20. )
    Alles anzeigen

    Und da kann ich auch noch nach auto.klima = 1 beliebig viele andere Einschränkungen was Austattung angeht angeben und das Ergebnis passt dann dementrsprechend

    funktioniert nicht:

    Quellcode

    1. SELECT
    2. *
    3. FROM
    4. auto LEFT JOIN buchen ON auto.aid = buchen.aid
    5. WHERE
    6. auto.klima=1
    7. AND
    8. auto.typ='Kombi'
    9. AND
    10. ISNULL(buchen.aid)
    11. OR
    12. (von <'2009-07-02'
    13. AND
    14. bis <'2009-07-02')
    15. OR
    16. (von <'2009-07-03'
    17. AND
    18. bis <'2009-07-03')
    Alles anzeigen
  • Sooo,

    nachdem die Applikation endlich fertig ist, konnte ich mich nun voll und ganz aufs Testen konzentrieren.
    Ich hoffe, ich habe diesmal alles richtig übernommen?

    SQL-Abfrage

    1. SELECT auto.raumnummer, auto.art, auto.klima, auto.navi, auto.raucher, auto.heizung
    2. FROM auto LEFT JOIN buchen ON auto.aid = buchen.aid
    3. where auto.klima=false
    4. AND auto.navi=false
    5. AND auto.heizung=false
    6. AND auto.raucher=false
    7. AND auto.art='kombi
    8. AND (ISNULL(buchen.raumnummer)
    9. OR (von <'2010-02-02' AND bis <'2010-02-02')
    10. OR (von <'2010-02-05' AND bis <'2010-02-05'))


    Leider muckt er auf, wenn ich zB für den Zeitraum vom 2010-01-19 bis 2010-02-02 ein auto reserviert habe und ich dann checken will, ob es vom 2010-01-19 bis 2010-02-03 frei ist.
    scheinbar prüft er nicht nach beiden Daten einzeln.

    Danke