Mysql query mit Bedingung
Hallo zusammen,
ich habe ein Formular mit 3 select-Feldern. Monat, Kunde und Mitarbeiter.
Daraus soll eine dynamische DB Abfrage entstehen.
So, nun kann ich natürlich mit php 8 verschiedene ifs bauen. Es soll entweder gefiltert werden, wenn zB ein spezifischer Kunde gewählt wurde, wenn kein spezifischer Kunde gewählt wurde, sollen alle Datensätze angezeigt werden.
Also kunde spezifisch ja nein, Mitarbeiter spezifisch ja nein, Datum spezifisch ja nein:
Was ich bräuchte ist sowas wie:
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.
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 versucht, dass um Codeschipsel zu erweitern.
Funktioniert nur für einen Teil der Kombis, weil je nach Filter der from - Teil unterschiedlich ist.
Rauskommen soll eine flexible Tabelle. Wo ich entweder sehen kann, wo der Mitarbeiter war, wo der Mitarbeiter am Monat x war. wann der Mitarbeiter beim Kunden A war und andersherum, wer beim Kunden A war, wer im Monat M beim Kunden A war, oder was im Monat 11 2021 gelaufen ist.
Der Tabellenaufbau:
Die Kunden und die Mitarbeiter sind via id verknüpft, das heißt ja, dass je nach Filter "from mitarbeiter" rein muss oder nicht. (oder "from kunden")
mfG
ich habe ein Formular mit 3 select-Feldern. Monat, Kunde und Mitarbeiter.
Daraus soll eine dynamische DB Abfrage entstehen.
So, nun kann ich natürlich mit php 8 verschiedene ifs bauen. Es soll entweder gefiltert werden, wenn zB ein spezifischer Kunde gewählt wurde, wenn kein spezifischer Kunde gewählt wurde, sollen alle Datensätze angezeigt werden.
Also kunde spezifisch ja nein, Mitarbeiter spezifisch ja nein, Datum spezifisch ja nein:
select taetigkeiten.*,taetigkeiten.id as tid, mitarbeiter.kuerzel,mitarbeiter.ausbildung,mitarbeiter.name as mitarbeiter,kunden.*,kunden.id as kid, infoarten.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
Was ich bräuchte ist sowas wie:
select taetigkeiten.*,taetigkeiten.id as tid, mitarbeiter.kuerzel,mitarbeiter.ausbildung,mitarbeiter.name as mitarbeiter,kunden.*,kunden.id as kid, infoarten.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 nichts; ansonsten 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.
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 versucht, dass um Codeschipsel zu erweitern.
$schnipselfuerkunde=" and taetigkeiten.kunde=".$kundeid." and taetigkeiten.kunde= kunden.id";
Funktioniert nur für einen Teil der Kombis, weil je nach Filter der from - Teil unterschiedlich ist.
Rauskommen soll eine flexible Tabelle. Wo ich entweder sehen kann, wo der Mitarbeiter war, wo der Mitarbeiter am Monat x war. wann der Mitarbeiter beim Kunden A war und andersherum, wer beim Kunden A war, wer im Monat M beim Kunden A war, oder was im Monat 11 2021 gelaufen ist.
Der Tabellenaufbau:
-- 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: `dummy`
--
-- --------------------------------------------------------
--
-- 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 */;
mfG
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 2163545354
Url: https://administrator.de/contentid/2163545354
Ausgedruckt am: 24.11.2024 um 05:11 Uhr
7 Kommentare
Neuester Kommentar
Moin,
eigentlich brauchst du keine If-Bedingungen.
Du kannst das wie folgt machen - und dabei mit JOINs arbeiten, was IMHO sinniger ist
die drei Variable im Set übernimmst du dann aus deinen Auswahlfeldern, die du (vermutlich) per POST oder was auch immer übergibst
Gruß
em-pie
eigentlich brauchst du keine If-Bedingungen.
Du kannst das wie folgt machen - und dabei mit JOINs arbeiten, was IMHO sinniger ist
SELECT
@postKunde
, @postMitarbeiter
, @postDatum
SET
@postKunde = NULLIF(4711, 0)
, @postMitarbeiter = NULLIF(815, 0)
, @postDatum = NULLIF('14.03.2022', '')
SELECT
taetigkeiten.*
, mitarbeiter.kuerzel
, mitarbeiter.ausbildung
, mitarbeiter.name as mitarbeiter
, kunden.*
, ia.name as infoart
from taetigkeiten as t
INNER JOIN kunden as k
on t.kunde = k.id
INNER JOIN mitarbeiter as m
on t.ausfuehrender = m.id
INNER JOIN infoarten as i
on t.informationsart_id = i.ID
WHERE
(t.kunde = @postKunde or @postKunde is null)
and (t.ausfuehrender = @postMitarbeiter or @postMitarbeiter is null)
and (t.datum = @postDatum or @postDatum is null)
ORDER BY
t.datum
die drei Variable im Set übernimmst du dann aus deinen Auswahlfeldern, die du (vermutlich) per POST oder was auch immer übergibst
Gruß
em-pie
Zitat von @tsunami:
@em-pie
Genau, die 3 Selects kommen via post.
Die Variable Kunde ist also entweder 0 => Filter ignorieren
oder !=0 => Filter
Die Zeilen 1-4 deklarieren grundsätzlich erst einmal Variablen innerhalb des SQL-Statements@em-pie
Genau, die 3 Selects kommen via post.
$kunde=0;
if(isset($_POST['kunde']))
$kunde=$_POST['kunde'];
oder !=0 => Filter
Die Zeilen 6-9 weisen den Variablen Werte zu. Hier kannst du eine via POST erhaltenen Variablen einfügen *
Was bedeutet der Part:
Ist das exemplarisch für die Variable Kunde?
Nein. Du hast doch in deinem Ausgangspost selbst mitgeteilt, dass Mitarbeiter der der Ausfuehrer ist.@postMitarbeiter
Also ist der Mitarbeiter dein eigenes Personal
Ich habe die Variablen alle mit
@post
begonnen, um optisch darauf hinzuweisen, dass die Inhalte aus einem POST-Statement stammen. Ich hätte auch die Variablen @pusemuckel
, @8041
und @Gandalf
nennen können, wäre dann aber weniger eindeutig gewesen.Versuche bitte zu verstehen, was oben passiert. Es erfüllt eigentlich genau deine Anforderung. Deine Filterung findet ja erst in den Zeilen 28 - 31 statt. Wobei nicht gegen 0 geprüft wird, sondern NULL (das eine ist die Zahl 0 das andere ist nichts). Wenn Kunde bzw. Mitarbeiter den Wert 0 inne haben, werden diese auf NULL gesetzt (siehe Zeile 6 - 9).
Also ist der Kunde = Variable oder die Variable ist leer (und somit werden alle Kunden gelistet)
(*) Hierzu noch eine Anmerkung
Prüfe bitte noch, ob die Inhalte valide sind. Der nächst beste pöhse Pursche fängt sonst mit SQL-Injections an!
Edit: Typo
Moin,
Ein Tipp: Formatiere deine SQL-Queries (und auch andere Quellcodes) ordentlich. das vereinfacht das Lesen ungemein.
Zu deinem Problem.
Mein Code oben ist ausschließlich SQL-Syntax. PHP streut da noch nicht ein.
Im SQL-Statement kann man mit Variablen arbeiten, erkennbar an einem @. Beginnt die Variable mit einem @@, so hadelt es sich um Systemvariablen.
In deinem Fall müssest du das, um das in PHP einzubinden, wie folgt aufbauen:
Die PHP-Variable
Edit: Typo
Ein Tipp: Formatiere deine SQL-Queries (und auch andere Quellcodes) ordentlich. das vereinfacht das Lesen ungemein.
Zu deinem Problem.
Mein Code oben ist ausschließlich SQL-Syntax. PHP streut da noch nicht ein.
Im SQL-Statement kann man mit Variablen arbeiten, erkennbar an einem @. Beginnt die Variable mit einem @@, so hadelt es sich um Systemvariablen.
In deinem Fall müssest du das, um das in PHP einzubinden, wie folgt aufbauen:
<?php
$kunde = 4711; //der Inhalt aus deinem POST. Habe es hier stark abgekürzt
$mitarbeiter = 815; //der Inhalt aus deinem POST. Habe es hier stark abgekürzt
$datum = "17.03.2022"; //der Inhalt aus deinem POST. Habe es hier stark abgekürzt
$strSqlQry = "SELECT
@postKunde
, @postMitarbeiter
, @postDatum
SET
@postKunde = NULLIF('" . $kunde . "', 0)
, @postMitarbeiter = NULLIF('" . $mitarbeiter . "', 0)
, @postDatum = NULLIF('". $datum . "', '')
SELECT
taetigkeiten.*
, mitarbeiter.kuerzel
, mitarbeiter.ausbildung
, mitarbeiter.name as mitarbeiter
, kunden.*
, ia.name as infoart
FROM taetigkeiten as t
INNER JOIN kunden as k
on t.kunde = k.id
INNER JOIN mitarbeiter as m
on t.ausfuehrender = m.id
INNER JOIN infoarten as i
on t.informationsart_id = i.ID
WHERE
(t.kunde = @postKunde or @postKunde is null)
and (t.ausfuehrender = @postMitarbeiter or @postMitarbeiter is null)
and (t.datum = @postDatum or @postDatum is null)
ORDER BY
t.datum";
?>
Die PHP-Variable
$strSqlQry
ist dann deine, mit der du das Statement "abfeuern" kannst.Edit: Typo