Ankündigung

Einklappen
Keine Ankündigung bisher.

Where Bedingung mit Filter

Einklappen

Neue Werbung 2019

Einklappen
Dieses Thema ist geschlossen.
X
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Where Bedingung mit Filter

    Hallo zusammen,
    ich habe ein Formular mit 3 select-Feldern. Monat, Kunde und Mitarbeiter.

    PHP-Code:
    select taetigkeiten.*,taetigkeiten.id as tidmitarbeiter.kuerzel,mitarbeiter.ausbildung,mitarbeiter.name as mitarbeiter,kunden.*,kunden.id as kidinfoarten.name as infoart
    from infoarten
    ,taetigkeiten,mitarbeiter,kunden
    where taetigkeiten
    .kunde=%s
    and taetigkeiten.ausfuehrender=%s
    and taetigkeiten.ausfuehrender=mitarbeiter.id
    and infoarten.id=taetigkeiten.informationsart_id
    and taetigkeiten.kunde=kunden.id
    and datum like '%s%%' order by datum 
    Bisher war es so, dass wenn zB Kunde =0 war, keine Datensätze gewählt wurden. So, nun kann es aber Sinn machen, dass man zB vom Mitarbeiter alle Tätigkeiten haben möchte, zB im Mai 2021 oder aber auch den gesamten Dtaenbestand der letzten 3 Jahre.
    Was ich also bräuchte, ist sowas wie
    PHP-Code:
    select taetigkeiten.*,taetigkeiten.id as tidmitarbeiter.kuerzel,mitarbeiter.ausbildung,mitarbeiter.name as mitarbeiter,kunden.*,kunden.id as kidinfoarten.name as infoart
    from infoarten
    ,taetigkeiten,mitarbeiter,kunden
    where 
    if(kunde==0;mache nichts;ansonsten kunde == 4)
    and if(
    taetigkeiten.ausfuehrender==0;mache nichts;ansonsten taetigkeiten.ausfuehrender==21
    and infoarten.id=taetigkeiten.informationsart_id
    and taetigkeiten.kunde=kunden.id
    and if(datum==0;mache nichtsansonsten datum like '2021-05%' order by datum 
    Ich hatte gesehen, dass es so was ähnliches mit case gibt, aber das war nur für die Ergebnisse. Also was weiß ich case monat=10 jahrezeit = Herbst.

    -- phpMyAdmin SQL Dump
    -- version 4.9.0.1
    -- https://www.phpmyadmin.net/
    --
    -- Host: 127.0.0.1
    -- Erstellungszeit: 14. Mrz 2022 um 10:40
    -- Server-Version: 10.3.16-MariaDB
    -- PHP-Version: 7.2.20

    SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
    SET AUTOCOMMIT = 0;
    START TRANSACTION;
    SET time_zone = "+00:00";


    /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
    /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
    /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
    /*!40101 SET NAMES utf8mb4 */;

    --
    -- Datenbank: `dok-o`
    --

    -- --------------------------------------------------------

    --
    -- Tabellenstruktur für Tabelle `taetigkeitendemo`
    --

    CREATE TABLE `taetigkeitendemo` (
    `id` int(11) NOT NULL,
    `datum` datetime NOT NULL,
    `kunde` int(5) NOT NULL,
    `ausfuehrender` int(11) NOT NULL,
    `prioritaet` int(1) NOT NULL,
    `informationsart_id` int(1) NOT NULL,
    `beschreibung` text COLLATE latin1_german1_ci NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci;

    --
    -- Indizes der exportierten Tabellen
    --

    --
    -- Indizes für die Tabelle `taetigkeitendemo`
    --
    ALTER TABLE `taetigkeitendemo`
    ADD PRIMARY KEY (`id`);

    --
    -- AUTO_INCREMENT für exportierte Tabellen
    --

    --
    -- AUTO_INCREMENT für Tabelle `taetigkeitendemo`
    --
    ALTER TABLE `taetigkeitendemo`
    MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
    COMMIT;

    /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
    /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
    /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
    Es sind also 3 select Felder, Kunde, Monat, Mitarbeiter.Diese werden per POST ans Formular geschickt. Nun kann ich natürlich auch das Ganze mit php lösen und sagen,
    PHP-Code:
    if($($kunde_id=0) and $datum==and $mitarbeiter==0){ $sql=...)
    if($(
    $kunde_id!=0) and $datum==and $mitarbeiter==0){ $sql=...)
    if($(
    $kunde_id=0) and $datum!=and $mitarbeiter==0){ $sql=...)
    if($(
    $kunde_id!=0) and $datum==and $mitarbeiter==0){ $sql=...)
    ... 
    ABer das muss doch eleganter gehen.
    Any idea?
    mfG
    tsunami

  • #2
    Bitte Code nicht als eine Wurst in eine Zeile schreiben. Sowas ist nicht wirklich lesbar.

    Außerdem ist es hilfreich bei Fragen zu SQL auch immer die Tabellenstruktur als SQL-Code mitzuliefern.

    Kommentar


    • #3
      Ich bin mir nicht sicher, ob ich Deine Frage bzw. die Beispielabfragen verstanden habe.

      Du solltest Dein Select so umbauen, dass Du ANSI Joins mit ihren Möglichkeiten verwenden kannst.
      Aus
      Code:
      Select t.*, k.* from tätigkeiten t, kunde k
      where t.kunde=k.id
      wird dann
      Code:
      Select t.*, k.*
        from tätigkeiten t
        join kunde k
          on t.kunde=k.id
      Ab da kannst Du mit der Wahl einer bestimmten Join Art, alle Tätigkeiten ausgeben, egal, ob ein Kunde zugeordnet ist oder nicht.
      Eine Join Variante davon nennt sich z.B. left join.
      Code:
      Select t.*, k.*
        from tätigkeiten t
        left join kunde k
          on t.kunde=k.id
      Wenn Du einen solchen Join optional einschränken möchtest, wäre eine solche Konstruktion möglich,
      wobei aram_Kunde einem Formularwert entspricht, der entweder eine konkrete ID enthält oder 0 = egal):
      Code:
      Select t.*, k.*
        from tätigkeiten t
        left join kunde k
          on (t.kunde=k.id
          and t.kunde=(CASE
                       WHEN :param_kunde = 0 THEN t.kunde
                       ELSE :param_kunde
                        END)
      Liefert immer alle Tätigkeiten, und wenn in DB vorhanden, dann mit zugehörigen Kundendaten. Falls über Kundenparameter eingeschränkt, nur Tätigkeiten mit passender Kundennummer.

      Anderes Thema, Du solltest die Datumsabfragen richtig parametrieren, ich hoffe die Spalte "Datum" hat auch einen Date Typ.

      Das Prinzip kann man auf andere Tabellen / Referenzen / Parameter ausdehnen.

      Kommentar


      • #4
        Perry Staltic Waow, das war schnell. Vielen Dank erstmal. Ich versuche ich ml anders zu beschreiben:
        Über die select-Boxen kann ich filtern. Ist kein Filter gesetzt zeige alle Datensätze.
        Ist der Filter Kunde gesetzt (zB Kunde X, es gibt aber mehrere), zeige nur Datensätze von dem Kunden x. Sind zusätzlich der Filter Mitarbeiter (Mitarbeiter A; es gibt aber Mitarbeiter A,B, C, D ...) gesetzt, zeige nur Datensätze von dem Kunden X, wo der Mitarbeiter A war. Nimmt man den Filter Kunden (X) raus, zeige alle Datensätze wo der Mitarbeiter A war. Das Ganze noch um den Monat eweitert (10 2021). Also alle 8 Kombis (0 = alleo der bestimmterDatensatz; 2 Zustände ; konkret oder allebei 3 Filtern=> 2^3 = . Alle Datensätze, Kunden x und Monat 10 2021, Kunde x und Mitarbeiter A und Datum 10 2021, Mitarbeiter A und Datum 10 2021 ... Es können also 0, 1, 2, oder 3 Filter gesetzt werden.
        Mein Problem ist, dass dann natürlich das from kunden nicht komplett rein darf, wenn kein Kunde gewählt ist. Lasse ich es weg, kennt er die Tabelle nicht. weil es sonst zuviele Datensätze ausgibt. Hatte noch versicht, dass um Codeschipsel zu ereitern.
        PHP-Code:
        $schnipselfuerkunde=" and taetigkeiten.kunde=".$kundeid." and taetigkeiten.kunde= kunden.id"
        Funktioniert nur für einen Teil der Kombis.

        Zu dem Code: Da fehlt mir sowas wie zB kunde=12 (nur Einsätze wo der Kunde 12 bedient wurde) and mitarbeiter = 0 (alle Mitarbeiter). Oder habe ich es verstanden, dass es sowas werden muss:
        Code:
         sprintf(Select t.*, k.*   from tätigkeiten t   left join kunde k    
        on (t.kunde=k.id    
        and t.kunde=(CASE                
         WHEN :%s = 0 THEN t.kunde                  
        ELSE :%s                  
        END)",mysqli_real_escape_string($conn,$kundenid))

        Kommentar


        • #5
          Also ehrlich gesagt, der Teil ist für mich unverständlich:
          Zitat von tsunami13 Beitrag anzeigen
          [USER="42600"] Also alle 8 Kombis (0 = alleo der bestimmterDatensatz; 2 Zustände ; konkret oder allebei 3 Filtern=> 2^3 = . Alle Datensätze, Kunden x und Monat 10 2021, Kunde x und Mitarbeiter A und Datum 10 2021, Mitarbeiter A und Datum 10 2021 ... Es können also 0, 1, 2, oder 3 Filter gesetzt werden.
          Kannst Du vielleicht noch mal klarer schreiben.

          Zitat von tsunami13 Beitrag anzeigen
          [USER="42600"]
          Zu dem Code: Da fehlt mir sowas wie zB kunde=12 (nur Einsätze wo der Kunde 12 bedient wurde) and mitarbeiter = 0 (alle Mitarbeiter). Oder habe ich es verstanden, dass es sowas werden muss:
          Code:
          sprintf(Select t.*, k.* from tätigkeiten t left join kunde k
          on (t.kunde=k.id
          and t.kunde=(CASE
          WHEN :%s = 0 THEN t.kunde
          ELSE :%s
          END)",mysqli_real_escape_string($conn,$kundenid))
          Was soll den $conn da drin?

          Es wird in diesem Abschnitt 2x der gleiche Parameter verwendet. Versuch mal bitte nur diesen Teilausdruck zu verstehen:

          Code:
          CASE
            WHEN :%s = 0 THEN t.kunde
            ELSE :%s
          END
          mit %s = 2x identischer Parameter, ergibt als ausgefüllter Parameter 2x den gleichen Wert. Probier es mit verschiedenen Paramter durch, vor allem mit parameter = 0, dann mit parameter != 0.
          Auf deutsch: Wenn Paramter :Kunde =0, gebe den aktuellen Wert aus der Spalte t.kunde zurück, sonst gebe den Paramter :Kunde direkt zurück. Damit hast Du eine variable Einschränkung.
          Bevor Du das alles in unformatiertem Code mit PHP vermischt, probiere es lieber direkt per SQL an der Console aus und schau Dir an, wie es funktioniert.


          Und ich habe geschrieben, dass der Code exemplarisch für Kunde umgesetzt ist, mit Mitarbeiter musst Du es nach dem gleichen Prinzip wie für Kunde erweitern, also den Join entsprechend um Mitarbeiter erweitern und die Case When Bedingung dafür eintragen.

          Kommentar


          • #6
            crosspost https://administrator.de/forum/mysql...163545354.html
            PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

            Kommentar


            • #7
              Bitte Forenregeln beachten.

              MOD: Thema Geschlossen

              Kommentar

              Lädt...
              X