Suchfunktion mit 2 Spalten

Doccos12

Grünschnabel
Guten Morgen,

Bis jetzt konnte ich großteils alles mit der Suchfunktion lösen jedoch häng ich jetzt bei einem Problem wo ich nicht weiterkomme :(

Ich will eine Suchfunktion programmieren wo Werte in mehreren Input/Checkboxen stehen, diese sich jedoch verändern können

Alle Form Elemente sind in einer Haupt und Untergruppe unterteilt
zb.:
Form 1: typ: input, HGroup: 1 SGroup:1
Form 1: typ: input, HGroup: 1 SGroup:2
Form 1: typ: checkbox, HGroup: 2 SGroup:1
Form 1: typ: checkbox, HGroup: 2 SGroup:2
Form 1: typ: input, HGroup: 3 SGroup:1

Also dachte ich an folgende SQL Struktur:
Tabelle data: <-hier befinden sich die Datensätze mit den Ergebnissen
idname
1Datensatz 1
2Datensatz 2
3Datensatz 3
Tabelle detail <- mit den Werten für die Suchfunktion
pid <-Parent idhid <-Hauptgruppecid <-Untergruppevalue <-Wert
11230
13110
1211
2221
21250
31260
3221

Per PHP Überprüfe ich welche Checkbox/Input aktiv ist und füge es dem Query hinzu.
Jedoch weiß ich nicht so ganz wie ich den Query formulieren soll, bis jetzt sieht er so aus:

PHP:
SELECT 
    data.id, data.name 
FROM 
    data
LEFT JOIN 
    detail ON detail.pid = data.id 
WHERE
    ( detail.hid = '1' AND detail.cid='1' AND detail.value='1' ) 
AND
    ( detail.hid = '2' AND detail.cid='1' AND detail.value='1' ) 
AND
    ... usw(je nachdem welcher input ausgewählt wurde)
GROUP BY 
    detail.pid
Gibt es eine Möglichkeit solch einen Query zu erstellen ?
Ohne das ich für jedes input Feld einen Join machen muss

Oder gibt es einen Besseren weg?

Hoffe ich hab mich verständlich ausgedrückt :)
mfg
 
Jepp. Ich habe dazu vor ieniger Zeit mal ein Eintrag in mein Wiki gemacht
PHP/MySQL Einfacher SQL-Filter aus $_POST zusammenstelle

Das Beispiel von dort kannst du einfach für dich umsetzen
PHP:
<!-- Formular -->
<form action="?" method="post">
    Text 1:<input type="text" name="text1" /><br />
    Text 2:<input type="text" name="text2" /><br />
    Zahl 3:<input type="text" name="zahl3" /><br />
    <input type="submit" name="submit" />
</form>
<hr />

<?php
// Prüfen ob das Formular gesendet wurde
if(isset($_POST['submit'])){
    // Array initializieren. Falls kein argument angegeben wurde,
    // dann ist die Argumentliste ein leeres Array
    $wheres = array();
    //Jedes Feld prüfen und ggf in den Where-Array einfügen
    if($_POST['text1']) $wheres[] = "text1='{$_POST['text1']}'";
    if($_POST['text2']) $wheres[] = "text2='{$_POST['text2']}'";
    if($_POST['zahl3']) $wheres[] = "zahl3={$_POST['zahl3']}";

    // Wenn Bedinungen vorhanden sind, WHERE-Teil des SQL-String zusammenstellen
    if(count($wheres)>0) $wherestring = "WHERE ".implode(' AND ', $wheres);
    //SQL-String zusammensetzen
    $sql = "SELECT * FROM mytable {$wherestring}";
    //TODO: Sql an die DB absetzen
    echo $sql;
}
?>
 
Wie man es von dir kennt, eine tolle Lösung für das Problem.

Aber sollte bei den IFs nicht noch mit isset geprüft werden ob es die POST-Variablen "text" überhaupt gibt. So wird doch ein Fehler ausgelöst!?

PHP:
if(isset($_POST['text1'])) $wheres[] = "text1='{$_POST['text1']}'";
 
Moin,

evlt. Post auch so umsetzen:

PHP:
$wheres=array();
// Die ungewünschten Post ausschließen, wie der Speicher-Button etc.
$del_post=array('submit','save');

unset($_POST['submit']);

foreach ($_POST as $key => $val) {
   if (!in_array($key,$del_post)) {
      $wheres[]=$key."='".mysql_real_escape_string($val)."'";
   }
}
 
So ähnlich hab ich es bei mir gelöst, jedoch hab ich das Problem das ich nicht verschiedene Spaltennamen (text1, text2, zahl3) sondern immer mit den gleichen Spaltennamen abfragen muss

PHP:
WHERE 
    ( detail.hid = '1' AND detail.cid='1' AND detail.value='1' )  
AND 
    ( detail.hid = '2' AND detail.cid='1' AND detail.value='1' )
Wenn ich das auflöse sucht er leider nach einem Datensatz wo detail.hid = 1 und detail.hid gleich 2 ist.
Was logischerweiße nicht möglich ist

Setze ich ein OR dazwischen also:
PHP:
WHERE 
    ( detail.hid = '1' AND detail.cid='1' AND detail.value='1' )  
OR 
    ( detail.hid = '2' AND detail.cid='1' AND detail.value='1' )

findet er zwar einen Eintrag jedoch auch wenn nur ein zustand zutrifft

meine letzte Überlegung war die anzahl der gefunden detail.pid zu zählen und dann zu überprüfen ob die Anzahl der detail.pid mit der Anzahl der Forms übereinstimmt
PHP:
SELECT  
    data.id, data.name , COUNT(detail.pid) as gefunden
FROM  
    data 
LEFT JOIN  
    detail ON detail.pid = data.id  
WHERE 
    (
      ( detail.hid = '1' AND detail.cid='1' AND detail.value='1' )  
    OR
      ( detail.hid = '2' AND detail.cid='1' AND detail.value='1' )  
    )
AND
     gefunden = '2' //Anzahl der Forms
GROUP BY  
    detail.pid

Aber leider kann ich 'gefunden' nicht im 'WHERE' berreich überprüfen
 
@Dimension
Schlecht. Ein WHERE sieht je nach Type anders aus. Du kannst/solltest nicht eine Zahl als Text vergleichen. Ein Datum muss wiederum zuerst richtig formatiert werden etc. Das geht bei deiner Schleife nicht.
Wenn man es wirklich variabel halten will, empfehle ich umsetzung etwa so:

PHP MySQL Variable Where mit Daten aus $_POST

Aber das ist nicht das Thema

@Doccos12
Jetzt versteh ich glaub was du haben willst

Deine Idee ist goldrichtig. Du kannst aber dein gefunden im HAVING-Teil überprüfen.
WHERE wird vor dem GROUP BY geprüft. Ergo gibts da noch kein count.
HAVING wird nach dem GROUP BY geprüft. Ergo kann man da auch count prüfen

SQL:
SELECT  
    data.id, 
    data.name
FROM  
    data 
LEFT JOIN  
    detail ON detail.pid = data.id  
WHERE 
    ( detail.hid = '1' AND detail.cid='1' AND detail.value='1' )  
    OR ( detail.hid = '2' AND detail.cid='1' AND detail.value='1' ) 
GROUP BY  
    detail.pid
HAVING
    COUNT(detail.pid) = 2
 
Zuletzt bearbeitet von einem Moderator:
Das hatte ich gerade gefunden ^^
Nur wie sieht es bei der Performance von Having aus ?

Oder gibt es einen besseren Weg für so eine art Suchfunktion?

Aber danke für die Hilfe :)
 
@yaslaw, natürlich muss man je nachdem sich entscheiden was man nehmen, bzw. was man umsetzen möchte, mit vielen Input-Feldern lohnt sich wiederrum, nach meiner Ansicht, es so zu lösen.

Wenn man nun Eingaben hat wie Zahlen, Datum etc. muss man es anders handhaben klar.
War ja nur ein Gedankenvorschlag.
 
Zurück