Ankündigung

Einklappen
Keine Ankündigung bisher.

Durchsuchen mehrerer Tabellen nach zwei Werten (in Reihenfolge)

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Durchsuchen mehrerer Tabellen nach zwei Werten (in Reihenfolge)

    Hallo Gemeinde,

    ich bin Neu hier und stehe vor einem (für mich) mittelschweren Problem. Und zwar möchte ich in einer Datenbank alle Tabellen nach zwei Kriterien durchsuchen lassen und bei positiver Übereinstimmung natürlich das Ergebnis ausgeben lassen. Die Basis ist, dass jedes der zwei Suchkriterien in einer Tabelle vorkommen muss, um berücksichtigt zu werden - Jedoch nur jeweils einmal. Bis jetzt hatte ich mir alles nötige Wissen (Codes, Abfragen usw) selbst "ergooglen" können, doch jetzt komm ich einfach nicht mehr weiter. Da ich scheinbar auch nicht weiß, wie ich mein Anliegen als eine knappe Suchabfrage formuliere.

    Ich erkläre einmal kurz den Aufbau der Tabellen:
    Jede Tabelle enthält die typische ID-Spalte und mehrere weitere Spalten. Eine von diesen wird nun nach zwei Werten durchsucht. In der Regel ist, wenn zutreffend, jeder gesuchte Wert nur einmal in der Tabelle vorhanden. Leider gibt es unabänderbare Ausnahmen, wo ein Wert mehr als einmal auftaucht - und genau dort beginnen die Probleme.

    Der normale Aufbau; jeder "wert" ist nur einmal vorhanden:
    Code:
    +----+------+------+
    | id | wert | iwas |
    +----+------+------+
    | 1  | 54   | A    |
    | 2  | 3    | B    |
    | 3  | 87   | C    |
    | 4  | 43   | D    |
    +----+------+------+
    Die Anomalie; "wert" ist doppelt (auch nur einmal, also mehrere Doppelte kommen nicht vor):
    Code:
    +----+------+------+
    | id | wert | iwas |
    +----+------+------+
    | 1  | 54   | A    |
    | 2  | 3    | B    |
    | 3  | 87   | C    |
    | 4  | 54   | D    |
    +----+------+------+
    Für die Tabellen verwende ich folgende Abfrage (läuft in einer Schleife, daher alle Tabellen der DB):
    PHP-Code:
    $sql MYSQL_QUERY("SELECT wert
                      FROM 
    $tabelle
                      WHERE wert IN ('
    $suchewerta', '$suchewertb')
                      HAVING COUNT(*) = 2
                      "
    ) or die(mysql_error().' ?!'); 
    Das klappt wunderbar, solange der Suchwert $suchewertb auch nur einmal in der Tabelle vorkommt. Das funktioniert natürlich auch bei doppeltem Wert, aber leider macht er nicht wie gewünscht weiter da HAVING COUNT(*) = 2 dann erfüllt ist.

    Mein Wunsch dazu ist nun die Abfrage so zu modifizieren, dass weiter nach den beiden Suchwerten (es müssen beide einmal vorkommen) gesucht wird, aber bei doppelten nur der berücksichtigt wird mit der höchsten ID, also im Bsp. dann nur ID 4 (54) und ID 1 (54) soll ignoriert werden. Dazu ist noch als Konstante zu nennen, dass die doppelten Werte immer an erster und letzter Stelle der betreffenden Tabelle stehen. Der Hintergrund sind weitere MYSQL_QUERYs nach der Suche, die jedoch nur funktionieren, wenn $suchewerta eine kleinere ID ausgibt als $suchewertb.

    Ich hoffe das einigermaßen verständlich rüber gebracht zu haben. Leider drehe ich mich diesbezüglich schon seit Tagen im Kreis. Immer wenn ich dachte einen Lösungsansatz gefunden zu haben, landete ich wieder beim Ausgangsproblem. Der mir erstmal am sinnig scheinendste Weg war eine verschachtelte MYSQL-Abfrage, jedoch scheitere ich an der Umsetzung selbiger.


    Bin für jeden Lösungsansatz offen, und bedanke mich schonmal fürs Lesen.

    lg
    JMD

  • #2
    Wenn deine geschilderten Randbedingungen alle so eingehalten werden sollte ein zusätzliches
    Code:
    ORDER BY id DESC
    LIMIT 2
    ausreichen.

    Beachte auch dies zu MYSQL_QUERY im Manual
    Warnung
    Diese Erweiterung ist seit PHP 5.5.0 als veraltet markiert und ist in PHP 7.0.0 entfernt werden. Verwenden Sie stattdessen die Erweiterungen MySQLi oder PDO_MySQL. Weitere Informationen finden Sie im Ratgeber MySQL: Auswahl einer API und den zugehörigen FAQ. Alternativen zu dieser Funktion umfassen:

    Kommentar


    • #3
      Was klappt wunderbar? Der gepostete Query ist weit von dem entfernt, was du dir wünschst und falsch. Es gibt in einer Tabelle auch keine erste und letzte "Stelle", solange keine Sortierung definiert ist. Und eine Separierung von gleichen Daten über mehrere Tabellen ist auch ein Nogo (wird über eine weitere Spalte separiert).
      Das was du willst, ist ziemlich einfach machbar. Die Frage die sich mir stellt, ist es sinnvoll? Du schreibst, du willst das als Basis für weitere Abfragen nehmen. Vielleicht erklärst du das mal genauer. Meistens kann sowas zusammengefasst werden.

      Das was du willst, kannst du mit zwei Queries machen, bzw. auch als Subqueries.
      PHP-Code:
      SELECT (SELECT MIN(idFROM ... WHERE wert 'werta') AS werta_id, (SELECT MIN(idFROM ... WHERE wert 'wertb') AS wertb_id 
      So bekommst du immer ein Datensatz, wo du auf werta_id und wertb_id !== null kontrollieren musst.

      PHP-Code:
      SELECT (SELECT MIN(idFROM ... WHERE wert 'werta') AS werta_id, (SELECT MIN(idFROM ... WHERE wert 'wertb') AS wertb_id HAVING werta_id IS NOT NULL AND wertb_id IS NOT NULL 
      So bekommst du nur ein Datensatz, wo es auch werta_id und wertb_id gibt.

      Mit MIN() oder MAX() kannst du bestimmen, ob du die größte oder kleinste Id haben willst. Wenn über Id Sortiert ist, hast du damit deine erste und letzte Stelle.

      Kommentar


      • #4
        Hallo,

        und erstmal vielen Dank für die Ratschläge.

        jspit : Das Anfügen bringt leider keine Veränderung. Also es funktioniert ebenso?!


        Natürlich ist es wichtig, klar zu machen was man mit dem Ergebnis eigentlich anstellen will. Deswg bitte ich um Entschuldigung, das nicht gleich mit genannt zu haben. Also: Es geht mir nur indirekt um die zu findenden Werte, die möchte ich gar nicht direkt ausgeben (durch das suchen, werden sie aber zwangsläufig erkannt und können genutzt werden). Wichtig ist nur, dass sie in einer Tabelle beide vorkommen. Ist dies der Fall, wird der entsprechende Tabellenname für eine weitere Verarbeitung benutzt. Und ich nehme an aus dem Grund bringt der Code von erc auch leider nur eine "Fehlermeldung" (der weiteren Verarbeitung).

        Momentan kommt die "Suche" eben nur nicht damit klar, wenn einer der beiden Suchwerte doppelt in der Tabelle vorkommt. Ist dem so, dann gilt das Kriterium als erfüllt und ich bekomme den Tabellennamen ausgegeben, obwohl der zweite Suchwert nicht einmal in der Tabelle vorkommt.

        Danke auch nochmal für den Hinweis mit der PHP-Version. Derzeit läuft das System leider auf einer veralteten Version, weshalb der Code noch wunderbar funzt. Ich werde den Rat aber berücksichtigen und den Quellcode umschreiben, sobald es reibungslos läuft.

        grüße
        JMD

        Kommentar


        • #5
          Zitat von JMD Beitrag anzeigen
          jspit : Das Anfügen bringt leider keine Veränderung. Also es funktioniert ebenso?!
          Die Aussage bringt uns nicht weiter. Ist soviel wert wie funktioniert nicht und ist keine Fehlerbeschreibung.
          Was hast du probiert mit welchen Daten und welchen Ergebnis?
          Gut wäre ein SQL-Fiddle, welches dein Problem zeigt.

          Bei mir hat es funktioniert. Ich habe die Zeilen aber nicht angefügt, sondern eingefügt.

          Kommentar


          • #6
            Die Begründung, warum mein Code ein Fehlermeldung bringt, erschließt sich mir nicht. Ich kann dir aber den Grund verraten. Ich erwarte das der Fragestelle mitdenkt, also du! Z.B. die ... sind ein gutes Zeichen, dass noch was zu ergänzen ist, zum Teil stecken in den Queries Syntaxfehler oder die Feldnamen stimmen nicht. Das sind alles keine unlösbaren Probleme, selbst für Anfänger. Die Fehlermeldungen, die die Datenbank in solchen Fällen zurückgibt, sind ziemlich eindeutig.

            PS: deine Anforderungen haben sich geändert. Wenn dich nur interessiert, ob die zwei Werte in der Tabelle vorkommen, kannst du auch aus dem COUNT(*) = 2 ein COUNT(DISTINCT wert) = 2 machen.

            PHP-Code:
            SELECT 1
            FROM $tabelle
            WHERE wert IN 
            ('suchewerta''suchewertb')
            HAVING COUNT(DISTINCT wert) = 

            Kommentar


            • #7
              @jspit: Was ich damit sagen wollte, der zusätzliche Code hatte keine Veränderung am Ergebnis hervorgebracht - es war ebenso, wie ohne diese zusätzlichen Zeilen. Es gab auch keine Fehlermeldung oder dergleichen.

              @erc: Der Ansatz mit DISTINCT hat mich den entscheidenden Schritt weiter gebracht. Vielen Dank dafür. Manchmal sieht man den Wald vor Bäumen nicht.

              Und mal noch so nebenbei: Ich habe wirklich sehr lange hin und her überlegt, ob ich diese Frage in einem Fachforum stelle. Und ich habe es sehr lange aufgeschoben aus dem Grund, dass einem immer - grundsätzlich - süffisante Antworten von Nutzern entgegen geworfen werden die dem Verfasser unterstellen eh keine Ahnung zu haben von dem was er da tut und/oder machen möchte. Dies kommt nicht nur hier, sondern nahezu überall vor. Was mir bei meiner recherche nach dem Problem im Vorfeld logischer Weise negativ aufgefallen ist. Es ist schön, wenn es einigen Leuten leichter von der Hand geht. Aber muss man da indirekte Unterstellungen mit Aussagen wie "erwarte das der Fragesteller mitdenkt" dem gegenüber an den Kopf knallen? Sowas erwarte ich auch. Selbstverständlich habe ich deine Code-Zeilen nicht einfach nur kopiert und eingefügt, sondern entsprechend angepasst. Ich mache das auch nicht erst seit gestern, aber alles wissen kann man eben nicht. Naja, wie dem auch sei: Unterm Strich ist für mich das Problem behoben, da ich mit dem Ansatz mir etwas gebaut habe was meinen Anforderungen entspricht. Wie gesagt, nochmal Danke.

              Kommentar


              • #8
                Deine Kritik zum Tonfall ist m.E. nicht ganz verkehrt, auch wenn es verbreitet ist, macht es das nicht besser.
                Andererseits versetz Dich bitte in die Situation derjenigen, die Unterstützung liefern (wollen). Allein anhand der (oft mageren) Fragen und Antworten auf Nachfragen, ist selten ersichtlich, welche und wieviel Versuche und Tests unternommen wurden, ein Problem zu lösen oder den Sachverhalt zu verstehen oder Dokumentation zu lesen und anzuwenden. Viele machen es sich mit platten Posts relativ einfach und erwarten fertigen Code ohne nachdenken zu müssen. Ob es so ist oder nicht, weiß man natürlich nie im Voraus, aber am anderen Ende des Internet sitzen auch nur Menschen und da fällt dann schnell mal ein unpassendes Wort.

                Dabei braucht es nicht soviel, sinnvolle Fragen zu stellen oder sinnvolle Antworten auf Rückfragen zu geben.
                Istsituation, Sollsituation, Beispieldaten, Abfrageversuche mit Result oder Fehlermeldung, etc. pp.
                Einfach beim nächsten Mal dran denken und nicht jedes Wort auf die Goldwaage legen.

                Kommentar

                Lädt...
                X