Announcement

Collapse
No announcement yet.

Eingrenzung mit WHERE-Statement

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

  • Eingrenzung mit WHERE-Statement

    Hallo,

    Manche auf den ersten Blick trivial erscheinende Dinge sind doch nicht so einfach wie es scheint ...

    <b>Problemstellung:</b><br>
    Verwendet wird Delphi 5 Enterprise und Interbase 5.6, Windows-2000 Server

    Eine Abfragemenge über mehrere Tabellen, abgerufen über TQuery soll mittels WHERE eingegrenzt werden, damit die erhaltene Datenmenge (über das Netz) klein bleibt und keine nichtbenötigten Daten übertragen werden. Die Eingrenzung bezieht sich sowohl auf einen Start- als auf einen Endbereich.

    Die Haupttabelle ist nach den Kriterien A,B und C sortiert. Nun kommt das Problem: <b>Die Eingrenzung soll nach allen 3 Kriterien möglich sein.</b> Ein einfaches Where-Statement ist also somit nicht möglich. Ich habe verschiedenste Where's probiert, es passiert aber immer wieder, daß hiebei Datensätze "nicht" übertragen werden, da es bei Betrachtung der Wahrheitstabelle Lücken gibt.

    Beispiel der Tabelle:
    FeldA,FeldB,FeldC

    1 a A
    1 a B
    1 a C
    1 b A
    1 b B
    1 b C
    1 b D
    1 c A
    1 c B
    1 c C
    2 a A
    2 a B
    2 a C
    2 b A
    2 b B
    usw.

    Der Startbereich sieht z.B. aus: FeldA >= 2, FeldB >= b, FeldC >= C
    Der Endbereich: FeldA <= 3, FeldB <= c, FeldC <= B

    Ein WHERE-Statement zur Abfrage der Startbedingung wie<br>
    WHERE ((FeldA >= DataA) and (FeldB >= DataB) and (FeldC >= DataC))<br>
    produziert die eingangs erwähnten Lücken (passende Datensätze werden nicht erfasst). DataA ist hier 2, DataB ist b usw.

    Eine Verschachtelung ab dem mittleren Statement <br>
    ... ((FeldB >= DataB) and (FeldA >= DataA)) ...<br>
    löst das Problem auch nicht. Auch der OR-Operator kann nicht angewandt werden, da sonst ungewollte Daten übertragen werden.

    Die Abfrage der Endebedingung scheint überhaupt nicht lösbar zu sein, da hier nicht einfach auf die Umkehrung der Operatoren geschlossen werden kann.

    In Pascal würde ich die Startabfrage wie folgt codieren:<br>
    if FeldA >= DataA then<br>
    if FeldB >= DataB then<br>
    if FeldC >= DataC then OK<br>
    Diese ist für den Startbereich wasserdicht und liefert immer die gewünschten Ergebnisse.

    Doch wie drücke ich das in SQL aus ???<br>
    Zudem soll noch berücksichtigt werden, daß wenn ein Eingabeparameter leer ist, nicht zur Eingrenzung herangezogen werden darf<br>
    (( if DataA > '') and (FeldA >= DataA)) then

    Für die Abfrage der Endbedingung habe ich nicht mal eine Pascal-Lösung, denn eine einfach Umkehrung der Operatoren produziert wiederum die ungewollten Datenlücken.

    Wie ist daher das Thema <b>Eingrenzung einer Datenmenge mit mehreren Abfragekriterien betreffend Beginn- und Startbereich zu lösen ?</b>

    Ich bitte um ein komplettes SQL-Statement, falls meine Fragestellung lösbar ist.

    Erklärung: mit FeldA ist das Spaltenfeld der Tabelle gemeint, DataA stellt das Eingabefeld dar, in welchem der Anwender den Start- bzw. Endebereich eingibt usw.

    Kann man dieses Thema eventuell mittels Stored Procedure lösen ?<br>
    Wie wird hier die Stored Procedure abgefasst und vor allem wie kann man sie in einem Where-Statement aufrufen ?

    Sind UDF's verwendbar (user defined functions) ?<br>
    Wie werden diese abgefasst und in einem Where-Statement angesprochen ?

    Kann man in einem Where-Statement eine Pascal-Variable (Parameter ?) abfragen ?

    Kann man in einer Query-Abfrage eine Variable (Parameter o.a.) auf Grund von Bedingungen setzen ?

    Ich hoffe, es gibt Profis welche mein Problem lösen können.

    Vielen Dank im Voraus<br>Helmut

  • #2
    Tschuldigung

    Die Tabelle formatiert

    1 a A <br>
    1 a B <br>
    1 a C <br>
    1 b A <br>
    1 b B <br>
    1 b C <br>
    1 b D <br>
    1 c A <br>
    1 c B <br>
    1 c C <br>
    2 a A <br>
    2 a B <br>
    2 a C <br>
    2 b A <br>
    2 b B usw. <br&gt

    Comment


    • #3
      Hallo Helmut,

      bei mir funktioniert das Ganze mit Start- und auch mit den Endwerten.
      Dabei habe ich genau die gleichen where-Klauseln verwendet wie Du.

      Der einzige Unterschied besteht darin, dass ich für die Selektionsbedingungen Konstanten verwendet habe (z.B. FeldA >=1, FeldB >= 'C' usw.).

      Bei welchen Wertepaaren funktioniert es bei Dir nicht?

      Meine Testumgebung ist IB6, WinNT 4.0 SP6a und getestet habe ich mit der IBConsole.

      Tschüß

      Torste

      Comment


      • #4
        Hallo Torsten,

        ich habe ein Excel-Sheet erstellt, bei dem ich theoretisch für jeden Datensatz eine Wahrheitstabelle gebildet habe. Nur dadurch habe ich bemerkt, daß bei obigen Where-Statements einige Datensätze <b>"nicht"</b> ausgegeben werden. Ich kann Dir die Tabelle gerne mailen, wenn Du mir Deine EMail-Adresse bekannt gibst. Hier wäre sie zu gross.

        Meine EMailadresse ist übrigens: [email protected]

        Ich arbeite mit Interbase 5.6, Windows-2000. Ich habe mich noch nicht getraut Interbase 6 zu installieren, da man von vielen Problemen hört.

        Konstanten kann ich nicht verwenden, da der User die Abfragegrenzen festlegt. Diese werden in Edit-Felder eingegeben und danach wird per Programmcode das Where-Statement gebildet.

        Gruss<br>
        Helmu

        Comment


        • #5
          Hallo,

          das Problem sind die NULL-Werte. Ich würde daher die Tabelle nur mit NOT NULL-Spalten deklarieren:
          <pre>
          CREATE TABLE TestTbl (
          ID INTEGER NOT NULL PRIMARY KEY,
          FeldA INTEGER NOT NULL,
          FeldB CHAR(1) NOT NULL,
          FeldC CHAR(1) NOT NULL);
          </pre>
          Wenn dann ein "Dummy-Zeichen" definiert wird, dass für "unbekannte" (d.h. nicht zugewiesene) Einträge steht, kann man für komplexe Abfragen mit Self Joins arbeiten, ohne auf einen OUTER JOIN zurückgreifen zu müssen.

          Allerdings sollte im Normalfall folgendes ausreichen, um für jede Spalte eine Start- und Endebedingung zu definieren, die alle erfüllt werden müssen:
          <pre>
          SELECT * FROM TESTTBL
          WHERE (FELDA BETWEEN 2 AND 3)
          AND (FELDB BETWEEN 'b' AND 'c')
          AND (FELDC BETWEEN 'B' AND 'C')
          </pre>
          Für den Fall, dass nicht nach allen 3 Spalten gleichzeitig gesucht werden soll, würde ich fallbezogen den WHERE-Part variieren (d.h. immer nur die Spalten abfragen, zu denen ein Suchwert vorliegt)

          Comment


          • #6
            Hallo,

            ich möchte zwecks Nachweis der Problematik eine Excel-Tabelle hier einfügen, wie kann man dies erreichen ?

            Kann man mit einem Texteditor (z.B. Word o.a.) formatiert schreiben und hier als HTML-Dokument einfügen ?

            Oder wie sonst kann man spaltengerecht schreiben ?

            Gruss<br>
            Helmu

            Comment


            • #7
              Hallo,

              wenn nicht zu viele Daten eingefügt werden müssen, würde ich wie folgt vorgehen: <br>
              a) FrontPage Express (IE-Zubehör) starten <br>
              b) Tabelle aus EXCEL über die Zwischenablage in das HTML-Dokument kopieren <br>
              c) In FrontPage Express über <i>Ansicht | HTML</i> in die direkte HTML-Darstellung wechseln und die Steuerzeichen in die Zwischenablage kopieren. <br>
              d) Text aus der Zwischenablage hier einfügen.

              Das könnte bei einer Tabelle so aussehen:

              <body bgcolor="#FFFFFF">
              <col width="80" span="3" style="width:60pt">
              <table border="1">
              <tr>
              <td align="center" width="80" height="17"
              style="height:12.75pt;width:60pt">&nbsp;</td>
              <td align="center" width="80" style="width:60pt">&nbsp;</td>
              <td align="center" width="80" style="width:60pt">&nbsp;</td>
              </tr>
              <tr>
              <td align="center" height="17" class="xl22"
              style="height:12.75pt">a</td>
              <td align="center" class="xl22">b</td>
              <td align="center" class="xl22">c</td>
              </tr>
              <tr>
              <td align="center" height="17" style="height:12.75pt"
              x:num>1</td>
              <td align="center">a</td>
              <td align="center">A</td>
              </tr>
              <tr>
              <td align="center" height="17" style="height:12.75pt"
              x:num>2</td>
              <td align="center">a</td>
              <td align="center">A</td>
              </tr>
              <tr>
              <td align="center" height="17" style="height:12.75pt">&nbsp;</td>
              <td align="center">&nbsp;</td>
              <td align="center">&nbsp;</td>
              </tr>
              </table>
              &#10

              Comment

              Working...
              X