Jörg: mysql: NULL Wert erzeugen

Hallo Forum,

meine Abfrage:

SELECT 
xyz
FROM myTable 
WHERE 
ID IN (4401,4724,4895,4896) 

soll einen NULL-Wert produzieren, wenn kein Eintrag für eine ID in der Tabelle enthalten ist.

Gibts da einen Kniff für?

Jörg

  1. Hallo Jörg,

    müsste ich jetzt selbst gucken; spontan weiß ich nichts.

    Ich sehe allerdings auch konzeptionelle Probleme. Dieser Select produziert ja keinen einzelnen Wert, sondern 0 bis 4 Rows mit je einer Spalte, je nach dem, wieviele der IDs existieren.

    Dein "soll einen Null-Wert produzieren" bedeutet also: Statt 0 Rows soll es eine Row geben, in der xyz geNULLt ist. Das kommt mir sehr abstrus vor, aber ich mistverstehe Dich ja vielleicht auch.

    Was willst Du erreichen?

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hi Rolf,

      Was willst Du erreichen?

      Es geht darum, dass ich Rechnungen erstellen möchte. Diese Abfrage zieht mir die Gesamt-Rabattsätze für die (4) Vorgänge, die in die Rechnung einfließen sollen. Anschließend mache ich aus der Ergebnismenge ein unique_array und verweigere die Fakturierung, wenn das übrig gebliebene Array mehr als 1 Element hat, da die Rechnung nur 1 Gesamtrabatt beinhalten darf, der in allen Vorgängen identisch ist.

      Jörg

      1. Hallo,

        wäre es vielleicht möglich, hier die max()-Funktion zu verwenden?

        Gruß
        Kalk

        1. wäre es vielleicht möglich, hier die max()-Funktion zu verwenden?

          Hallo Kalk,

          inwiefern?

          Das Problem ist ja, dass von den (in obigem Beispiel) 4 Vorgängen überhaupt nur 2 Vorgänge in der Tabelle erfasst sind.

          Soll heißen, diese beiden müssten mit 0% gewertet werden. Wenn die übrigen Beiden auch 0% sind, kein Problem. Ansonsten schon.

          Jörg

          1. Hallo,

            mysql kennt offenbar max() nicht (mehr?).

            inwiefern?

            Vielleicht verstehe ich dein Problem nicht, aber greatest() liefert im Zweifelsfall auch Null zurück…

            Gruß
            Kalk

            Edith widerspricht meiner Theorie.

            1. Hallo Kalk,

              Vielleicht verstehe ich dein Problem nicht, aber greatest() liefert im Zweifelsfall auch Null zurück…

              Kannst du mir erklären, was Du vorhast? Ich erkenne den Mehrwert grade nicht. 🙂

              Jörg

              1. Hallo,

                Kannst du mir erklären, was Du vorhast?

                vielleicht ist es andersrum sinnvoller? So in der Art, dass du genauer erklärst was du vorhast?

                Ich erkenne den Mehrwert grade nicht. 🙂

                Meine Idee läuft auf den Mehrwert für den Kunden hinaus, also den maximalen Rabatt rausschinden ;)

                Gruß
                Kalk

      2. Hallo Jörg,

        das ist mir nicht konkret genug.

        Diese Abfrage zieht mir die Gesamt-Rabattsätze für die (4) Vorgänge, die in die Rechnung einfließen sollen.

        D.h. dass es 4 sind, ist jetzt nur ein Beispiel; es könnte auch nur einer sein oder 17?

        Und "xyz" ist nicht nur eine Column, sondern es sind etliche Spalten? D.h. du hast einen Select, und der liefert Rows. Und diese Rows - was passiert damit? Vor allem: wo? Denn dieser Satz ist mir ein Rätsel:

        Anschließend mache ich aus der Ergebnismenge ein unique_array

        Bitte, was machst Du? Eine SQL Operation "unique array" kenne ich nicht. Ich kenne DISTINCT - was aber Rows liefert, kein Array. MySQL kennt keine Arrays (es sei denn, als Teil einer JSON Operation). PHP kennt Arrays, und eine array_unique Funktion, aber die kann man nicht auf ein Array aus Rows anwenden. Das Entfernen von Duplikaten wäre mit einem SELECT DISTINCT auf SQL Ebene ohnehin einfacher. Wenn Du denn echte Duplikate im Ergebnis hast, wo alle - wirklich alle - Spalten gleich sind.

        und verweigere die Fakturierung, wenn das übrig gebliebene Array mehr als 1 Element hat

        Das klingt jetzt nicht mehr nach SQL, eher nach PHP. Deine Frage hatte aber MYSQL als Tag. Deswegen weiß ich immer noch nicht, auf welchem Pfad Du unterwegs bist, nach was für einem NULL Du suchst und was Du dann damit anzufangen gedenkst.

        Wenn Du ohnehin im PHP unterwegs bist, sollte doch ein IF reichen, um die Anzahl der Rows nach den Duplikatentfernung zu prüfen.

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Hallo Rolf,

          D.h. dass es 4 sind, ist jetzt nur ein Beispiel; es könnte auch nur einer sein oder 17?

          Stimmt.

          Und "xyz" ist nicht nur eine Column, sondern es sind etliche Spalten?

          Nein, das ist tatsächlich nur 1 column.

          Anschließend mache ich aus der Ergebnismenge ein unique_array

          Bitte, was machst Du? Eine SQL Operation "unique array" kenne ich nicht.

          Achso... natürlich bin ich jetzt grad im php-Kontext unterwegs. Sorry, ich dachte, das sei klar. 😌

          Wenn Du ohnehin im PHP unterwegs bist, sollte doch ein IF reichen, um die Anzahl der Rows nach den Duplikatentfernung zu prüfen.

          Sehe ich ähnlich. Aber die nicht vorhandenen Einträge sind ja gar nicht in der Ergebnismenge. 🙃

          In die relevante Tabelle kommen die Vorgänge erst, wenn eine AB darüber erstellt wird. Gibt aber Vorgänge, über die keine AB erstellt wird, dann fehlt der komplette Vorgang in der Tabelle aber.

          Jörg

          1. Hallo Jörg,

            Nein, das ist tatsächlich nur 1 column.

            Dann sollte ein SELECT DISTINCT xyz möglich sein, um Duplikate auszublenden. Oder verstehst Du unter einem "unique array" in PHP was Spezielles?

            Achso... natürlich bin ich jetzt grad im php-Kontext unterwegs. Sorry, ich dachte, das sei klar.

            Nein, wie denn. Du hast den Thread mit MYSQL getaggt.

            Um die Erkenntnis voranzubringen - Du schriebst an Tabellenkalk:

            Das Problem ist ja, dass von den (in obigem Beispiel) 4 Vorgängen überhaupt nur 2 Vorgänge in der Tabelle erfasst sind.

            Soll heißen, diese beiden müssten mit 0% gewertet werden.

            Jetzt wird ein ganzer Schuhladen draus.

            Du versuchst also - wenn ich die ID mal mit in das Ergebnis nehme - so was zu bekommen, wenn die IDs 4724 und 4896 nicht in myTable enthalten sind:

            ID      xyz
            4401    5
            4724    null (oder 0)
            4895    7
            4896    null (oder 0)
            

            Wenn ich das richtig deute, ist es Dir doch egal, welche IDs nicht da sind. Wichtig ist nur, dass welche fehlen. Wenn welche fehlen, wertest Du sie mit 0% und daraus folgt: diejenigen, die vorhanden sind, müssen 0% enthalten, damit du fakturieren kannst.

            Wie wäre es mit

            SELECT xyz, COUNT(*) as Anzahl
            FROM myTable 
            WHERE ID IN (....)
            GROUP BY xyz
            

            Nehmen wir noch an, dass Du in $numIDs die Anzahl der IDs stehen hast, die Du in die IN Klausel hineingibst.

            Du bekommst:

            • 0 Treffer: Kein Rabatt
            • 1 Treffer UND Anzahl == $numIDs - Rabatt = xyz
            • 1 Treffer UND Anzahl < $numIDs UND xyz = 0: Okay, kein Rabatt
            • 1 Treffer UND Anzahl < $numIDs UND xyz > 0: Keine Fakturierung weil Widerspruch zu den als 0 angenommenen Sätzen
            • 2 Treffer oder mehr: Keine Fakturierung weil Widerspruch in den gefundenen Sätzen

            Rolf

            --
            sumpsi - posui - obstruxi
            1. Hallo Rolf,

              Jetzt wird ein ganzer Schuhladen draus.

              Du versuchst also - wenn ich die ID mal mit in das Ergebnis nehme - so was zu bekommen, wenn die IDs 4724 und 4896 nicht in myTable enthalten sind:

              ID      xyz
              4401    5
              4724    null (oder 0)
              4895    7
              4896    null (oder 0)
              

              Wenn ich das richtig deute, ist es Dir doch egal, welche IDs nicht da sind. Wichtig ist nur, dass welche fehlen. Wenn welche fehlen, wertest Du sie mit 0% und daraus folgt: diejenigen, die vorhanden sind, müssen 0% enthalten, damit du fakturieren kannst.

              Ja, sämtliche Annahmen sind korrekt. Danke für das Hineindenken in die Materie. ich hätte das besser erklären sollen/können.

              Wie wäre es mit

              SELECT xyz, COUNT(*) as Anzahl
              FROM myTable 
              WHERE ID IN (....)
              GROUP BY xyz
              

              Nehmen wir noch an, dass Du in $numIDs die Anzahl der IDs stehen hast, die Du in die IN Klausel hineingibst.

              Du bekommst:

              • 0 Treffer: Kein Rabatt
              • 1 Treffer UND Anzahl == $numIDs - Rabatt = xyz
              • 1 Treffer UND Anzahl < $numIDs UND xyz = 0: Okay, kein Rabatt
              • 1 Treffer UND Anzahl < $numIDs UND xyz > 0: Keine Fakturierung weil Widerspruch zu den als 0 angenommenen Sätzen
              • 2 Treffer oder mehr: Keine Fakturierung weil Widerspruch in den gefundenen Sätzen

              Mann, ist das clever! 👍 Ich habe länger gebraucht, zu verstehen, was Du da machst. Ich glaube, ich habe es jetzt, Du nutzt eine Kombination aus Ergebnis, Input und Ausschlußverfahren. Saugut!

              Ich werde es am Donnerstag in der Praxis ausprobieren und berichten. Danke für die Hilfe.

              Jörg

              1. Hallo Jörg,

                Erfolg ist bekannlich eine Mischung aus etwas Inspiration und viel Transpiration.

                Idee 1: ich überlasse SQL das, was es am besten kann: Gruppieren und Zählen. Das hättest Du in PHP (beim Bilden des Unique Array) von Hand tun müssen.

                Idee 2: Man braucht nicht zu zählen, was man berechnen kann.

                Schön, dass ich Dich inspirieren konnte. Noch schöner, dass ich das Transpirieren Dir überlassen kann 😂

                Rolf

                --
                sumpsi - posui - obstruxi
                1. Hallo Rolf,

                  Erfolg ist bekannlich eine Mischung aus etwas Inspiration und viel Transpiration.

                  In mein Sprachrepertoir aufgenommen 😉

                  Wirklich imposant in seiner Praxisauswirkung, habe es gerade eingesetzt. Funktioniert 1A. Und ich liebe solche kreativen Lösungen wirklich. Die machen richtig Spaß, finde ich.

                  Vielen dank nochmal 👍

                  Jörg