script42: MySQL Spalten mit bestimmter Eigenschaft zählen

Hallo, liebe Forumsmitglieder,

ich habe eine Tabelle, in der es u.a. die Spalten "Termin1", "Termin2", "Termin3" gibt. Manchmal ist kein Termin belegt, manchmal 1, manchmal 2, manchmal 3. Ich würde gerne für jede Zeile abfragen, wieviele Termine jeweils vergeben wurden, also wieviele der Spalteneinträge unter Termin1-3 jeweils nicht NULL sind. Als Ergebnis hätte ich dann gerne eine einspaltige Tabelle mit der Anzahl (also 0, 1, 2 oder 3) pro Zeile. COUNT zählt mir ja nur die Zeilen, oder? Geht das irgendwie?

Danke für Eure Hilfe, Kerstin

akzeptierte Antworten

  1. Tach!

    ich habe eine Tabelle, in der es u.a. die Spalten "Termin1", "Termin2", "Termin3" gibt. Manchmal ist kein Termin belegt, manchmal 1, manchmal 2, manchmal 3.

    Gleichartige Daten sind besser in Zeilen statt in Spalten angeordnet sein, dann zählt man einfach ohne weitere Verrenkungen. Aber sei es drum, es geht auch so, wenn auch langsam mit Full-Table-Scan.

    Ich würde gerne für jede Zeile abfragen, wieviele Termine jeweils vergeben wurden, also wieviele der Spalteneinträge unter Termin1-3 jeweils nicht NULL sind.

    SELECT 
      IF(Termin1 IS NULL, 0, 1) + 
      IF(Termin2 IS NULL, 0, 1) + 
      IF(Termin3 IS NULL, 0, 1) Anzahl_Termine FROM ...
    

    dedlfix.

    1. Hi,

      Gleichartige Daten sind besser in Zeilen statt in Spalten angeordnet sein, dann zählt man einfach ohne weitere Verrenkungen. Aber sei es drum, es geht auch so, wenn auch langsam mit Full-Table-Scan.

      Hm. Den Zusammenhang zum Full-Table-Scan sehe ich jetzt nicht - der wäre gegeben, wenn da noch eine Abfrage der Anzahl als Bedingung auftaucht. Solange das nur im select und nicht im where auftaucht, sollte das nix ändern an einer Index-Nutzung.

      cu,
      Andreas a/k/a MudGuard

      1. Tach!

        Gleichartige Daten sind besser in Zeilen statt in Spalten angeordnet sein, dann zählt man einfach ohne weitere Verrenkungen. Aber sei es drum, es geht auch so, wenn auch langsam mit Full-Table-Scan.

        Hm. Den Zusammenhang zum Full-Table-Scan sehe ich jetzt nicht - der wäre gegeben, wenn da noch eine Abfrage der Anzahl als Bedingung auftaucht. Solange das nur im select und nicht im where auftaucht, sollte das nix ändern an einer Index-Nutzung.

        Ich kann mir grad nicht vorstellen, wie die Termine gezählt werden sollen, ohne jeden Datensatz einzeln anzuschauen.

        dedlfix.

        1. Hi,

          Ich kann mir grad nicht vorstellen, wie die Termine gezählt werden sollen, ohne jeden Datensatz einzeln anzuschauen.

          ja - aber das erfolgt ja erst, nachdem die Datensätze ausgewählt wurden. Und bei der Auswahl kommt ggf. der Full Table Scan zum Einsatz oder eben nicht.

          Warum sollte z.B., wenn per WHERE 3 von 17 Millionen Datensätzen ausgewählt werden, zum Zählen der Termine in den 3 Datensätzen die komplette Tabelle gescannt werden?

          cu,
          Andreas a/k/a MudGuard

          1. Hallo MudGuard,

            Warum sollte z.B., wenn per WHERE 3 von 17 Millionen Datensätzen ausgewählt werden, zum Zählen der Termine in den 3 Datensätzen die komplette Tabelle gescannt werden?

            „Ich würde gerne für jede Zeile abfragen, …“ (Hervorhebung von mir)

            Bis demnächst
            Matthias

            --
            Pantoffeltierchen haben keine Hobbys.
          2. Tach!

            Ich kann mir grad nicht vorstellen, wie die Termine gezählt werden sollen, ohne jeden Datensatz einzeln anzuschauen.

            ja - aber das erfolgt ja erst, nachdem die Datensätze ausgewählt wurden. Und bei der Auswahl kommt ggf. der Full Table Scan zum Einsatz oder eben nicht.

            Warum sollte z.B., wenn per WHERE 3 von 17 Millionen Datensätzen ausgewählt werden, zum Zählen der Termine in den 3 Datensätzen die komplette Tabelle gescannt werden?

            Von einer Einschränkung der Datenmenge war keine Rede. Aber selbst wenn, kann man die Anforderung "(also 0, 1, 2 oder 3) pro Zeile" nur mit der vollen (Rest-)Datenmenge erzeugen, nicht mit einer reduzierten.

            dedlfix.

    2. Super, danke!

  2. Hi,

    ich habe eine Tabelle, in der es u.a. die Spalten "Termin1", "Termin2", "Termin3" gibt.

    klingt nach Normalisierungs-Bedarf …

    Manchmal ist kein Termin belegt, manchmal 1, manchmal 2, manchmal 3. Ich würde gerne für jede Zeile abfragen, wieviele Termine jeweils vergeben wurden, also wieviele der Spalteneinträge unter Termin1-3 jeweils nicht NULL sind.

    in Oracle würde ich decode(termin1, null, 0, 1) + decode(termin2, null, 0, 1) + decode(termin3, null, 0, 1) verwenden.

    Für MySql könnte es (ungetestet) evtl. mit if(termin1 is null, 0, 1) + if(termin2 is null, 0, 1) + if(termin3 is null, 0, 1) oder so ähnlich funktionieren.

    Sinnvoller wäre m.E. aber eher die Normalisierung.

    cu,
    Andreas a/k/a MudGuard

    1. 😀 Habe schon befürchtet, dass das jetzt kommt!
      Tatsächlich gibt es bei mehreren Tabellen dieser Datenbank Bedarf für Normalisierung, doch ist das zeitlich gerade nicht drin. Muss das mal in einer ruhigen Minute machen.
      Danke für den if-Tipp, werde mich mal schlaumachen, ob es das in MySQL gibt.
      Herzliche Grüße
      Kerstin