Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Datenbankabfrage mit or Klausel

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von motto1234, 20 Dezember 2015.

  1. motto1234

    motto1234 Benutzer

    Hallo an alle,

    ich fange gerade erst mit Datenbankabfragen und komme einfach nicht weiter.
    Ich habe ein Buchhaltungsprogramm (GS-Auftrag) was seine Daten in einer MySQL Datenbank speichert. Auf diese Datenbank kann nur lesend zugegriffen werden.
    Ich muss eine Abfrage erstellen damit Weihnachtspost verschickt werden kann.

    Ich habe schon einiges hinbekommen aber eben noch nicht alles :-((
    In meiner WHERE Klausel ist eine OR Anweisung die einfach nicht will. Wenn ich die OR Klausel weglasse kommen die Ergebnisse. Ist die OR -Klausel vorhanden läuft die Abfrage ca. 15 Minuten und bricht dann mit dem Fehler out of memory ab.

    Ich hoffe das mir geholfen werden kann.

    Die aktuelle Abfrage sieht so aus

    SELECT DISTINCT
    sg_adressen.Post1,
    sg_adressen.Post2,
    sg_adressen.Post3,
    sg_adressen.Post4,
    sg_adressen.Post5,
    sg_adressen.Post6,
    sg_auf_fschrift.ERFART,
    sg_auf_fschrift.ENDPRB,
    sg_auf_fschrift.DATUM,
    sg_adr_bemerkung.Bemerkung,
    sg_adressen.Suchbegriff
    FROM
    sg_adressen ,
    sg_adr_bemerkung,
    sg_auf_fschrift
    WHERE
    sg_adr_bemerkung.Bemerkung = "weih15"
    or (
    sg_adressen.SG_Adressen_PK = sg_adr_bemerkung.SG_Adressen_FK AND
    sg_adressen.SG_Adressen_PK = sg_adr_bemerkung.SG_Adressen_FK AND
    sg_adressen.SG_Adressen_PK = sg_auf_fschrift.SG_ADRESSEN_FK AND
    sg_auf_fschrift.ENDPRB >= "790" AND
    sg_auf_fschrift.DATUM LIKE "2015%" AND
    sg_auf_fschrift.ERFART = "04RE"
    )

    Vielen Dank für eure Hilfe
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Schwer zu erraten was Du erreichen willst. Aber das, was Du im OR (....) stehen hast sieht (zum Teil, die ersten 3 Zeilen) eher nach Join-Condition aus. Stelle die Abfrage auf sauber Join-Syntax um, das könnte helfen.
     
  3. motto1234

    motto1234 Benutzer

    Vielen Dank für die Antwort,

    Leider bin ich totaler Anfänger was Datenbanken betrifft. Die Sache mit dem Join habe ich noch nicht verstanden.
    Ich versuche mal die Aufgabe zu erläutern.
    Es gibt in der Datenbank 179 Tabellen. In drei von den Tabellen stehen Daten, die ich brauche.
    1. Tabelle sg_adressen stehen die Adressdaten von allen Kunden.
    2. Tabelle sg_auf_fschrift stehen die Daten von Rechnungen, Angeboten .......
    3. Tabelle sg_adr_bemerkung steht in der Spalte Bemerkung, ob der Kunde egal welcher Umsatz und Letztkontakt er hatte trotzdem Weihnachtspost bekommen soll.

    Aufgabe:
    Es sollen alle Kundenadressen gefunden werden die
    1. eine Rechnung größer 790 Euro haben und
    2. eine Rechnung im Jahr 2015 erhalten hatten
    3. oder die Information in der 3. Tabelle steht das sie Weihnachtspost bekommen sollen
     
  4. akretschmer

    akretschmer Datenbank-Guru

    Vereinfacht:

    Code:
    test=*# create table kunden (id int primary key, name text);   
    CREATE TABLE   
    test=*# create table rechnung (kunde int references kunden, datum date, betrag int);
    CREATE TABLE   
    test=*# create table kunden_info (kunde int references kunden, brief bool);
    CREATE TABLE   
    test=*# copy kunden from stdin;   
    Enter data to be copied followed by a newline.   
    End with a backslash and a period on a line by itself.   
    >> 1  kunde1
    >> 2  kunde2
    >> \.
    COPY 2
    test=*# insert into rechnung values (1, '2015-01-01', 20);
    INSERT 0 1
    test=*# insert into rechnung values (2, '2014-01-01', 2000);
    INSERT 0 1
    test=*# insert into kunden_info values (1, true);
    INSERT 0 1
    test=*# insert into kunden_info values (2, true);
    INSERT 0 1
    
    Du hast nun:

    Code:
    test=*# select * from kunden;
     id |  name
    ----+--------
      1 | kunde1
      2 | kunde2
    (2 rows)
    
    test=*# select * from rechnung ;
     kunde |  datum  | betrag
    -------+------------+--------
      1 | 2015-01-01 |  20
      2 | 2014-01-01 |  2000
    (2 rows)
    
    test=*# select * from kunden_info ;
     kunde | brief
    -------+-------
      1 | t
      2 | t
    (2 rows)
    
    Wir fragen ab:

    Code:
    test=*# select k.id from kunden k left join rechnung r on k.id=r.kunde where extract('year' from datum) = 2015 or betrag > 10000;
     id   
    ----   
      1   
    (1 row)   
    
    test=*# select k.id from kunden k left join rechnung r on k.id=r.kunde where extract('year' from datum) = 2015 or betrag > 1000;
     id
    ----
      1
      2
    (2 rows)
    
    test=*# select k.id from kunden k left join rechnung r on k.id=r.kunde left join kunden_info ki on k.id=ki.kunde where extract('year' from datum) = 2015 or betrag > 10000 or ki.brief;
     id
    ----
      1
      2
    (2 rows)
    
    test=*# select k.id from kunden k left join rechnung r on k.id=r.kunde left join kunden_info ki on k.id=ki.kunde where extract('year' from datum) = 2015 or betrag > 10000 or ki.brief;
     id
    ----
      1
      2
    (2 rows)
    
    Versuch es zu verstehen, ist ganz simpel.
     
  5. motto1234

    motto1234 Benutzer

    Vielen Danke für Deine Antwort. Ich werde versuchen dahinter zu steigen und mich ggf. noch mal melden
     
  6. motto1234

    motto1234 Benutzer

    so ich bins noch mal ;-(
    folgende Abfrage habe ich mit Hilfe von akretschmer zusammengebastelt :)

    select distinct
    a.Post1,
    a.Post2,
    a.Post3,
    a.Post4,
    a.Post5,
    a.Post6,
    a.Post7
    from
    sg_adressen a
    left join
    sg_auf_fschrift f on
    a.SG_Adressen_PK=f.SG_ADRESSEN_FK
    left join
    sg_adr_bemerkung b on
    a.SG_Adressen_PK=f.SG_ADRESSEN_FK
    where
    extract(year from DATUM) = 2015
    or
    ENDPRB >= "790"
    or
    ERFART = "04RE"

    Nach 6 Minuten Abfragezeit habe ich die Sache erst einmal abgebrochen. Zum Testen nutze ich Navicut und den Query Editor.
    Gibt es noch Rettung für mich??
     
  7. akretschmer

    akretschmer Datenbank-Guru

    Was sagt Explain? Vermutlich fehlen Indexe. Das extract() funktioniert? In MySQL?
     
  8. motto1234

    motto1234 Benutzer

    Ich habe vor die Abfrage mal ein Explain vor SELECT gesetzt und "extract(year from DATUM) = 2015" durch "f.DATUM LIKE "2015%"" ersetzt.
    Die Abfrage mit LIKE hatte schon mal Ergebnisse geliefert. Die Ausgabe mit EXPLAIN sieht so auf

    1 SIMPLE a ALL 7629 Using temporary
    1 SIMPLE f ref sg_auf_fschrift11 sg_auf_fschrift11 5 mand5.a.SG_Adressen_PK 1 Distinct
    1 SIMPLE b ALL 7638 Using where; Distinct
     
  9. akretschmer

    akretschmer Datenbank-Guru

    ja, offenbar fehlen passende Indexe. Das MySQL-Explain ist halt wie MySQL selbst: grottig. Funktionale Indexe kann es nicht (für die erste Where-Condition sinnvoll). Using temporary ist halt auch von der Performance nicht prall.
     
  10. motto1234

    motto1234 Benutzer

    Ich werde es weiter probieren und das Ergebnis mitteilen.
    Erst mal vielen Dank für Deine Hilfe akretschmer.
     
    akretschmer gefällt das.
  11. Hubertus

    Hubertus Fleissiger Benutzer

    Statt f sollte es b heißen:

    select distinct
    a.Post1,
    a.Post2,
    a.Post3,
    a.Post4,
    a.Post5,
    a.Post6,
    a.Post7
    from
    sg_adressen a
    left join
    sg_auf_fschrift f on
    a.SG_Adressen_PK=f.SG_ADRESSEN_FK
    left join
    sg_adr_bemerkung b on
    a.SG_Adressen_PK=b.SG_ADRESSEN_FK
    where
    extract(year from DATUM) = 2015
    or
    ENDPRB >= "790"
    or
    ERFART = "04RE"
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden