PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr

PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr (https://www.php-resource.de/forum/)
-   PHP Developer Forum (https://www.php-resource.de/forum/php-developer-forum/)
-   -   MySQL / PHP Alle überschneidungen anzeigen (https://www.php-resource.de/forum/php-developer-forum/105130-mysql-php-alle-ueberschneidungen-anzeigen.html)

Koda 03-07-2015 10:23

MySQL / PHP Alle überschneidungen anzeigen
 
Guten Morgen

Ich habe hier folgende Datenbankstruktur und würde gerne die Überschneidungen finden. Da ich bisher nichts konkretes gefunden habe weiss ich nicht ob es vielleicht sogar mit mysql direkt möglich ist:

Da die Datenbankstruktur sehr gross ist habe ich es hier mal etwas abgekürzt und geändert. Ich hoffe so ist es verständlicher bei meinen Wirren gedankengängen :D

Code:

obst
OID | obst
1 | Apfel
2 | Banane
3 | Orange
4 | Mandarine
....

person
PID | person
1 | Hans
2 | Peter
3 | Marlise
4 | Sandra
...

obst_to_person
OID |PID
1 | 1 (Apfel - Heinz)
2 | 1 (Banane - Heinz)
3 | 1 (Orange - Heinz)
1 | 2 (Apfel - Peter)
3 | 2 (Orange - Peter)
1 | 3 (Apfel - Marlise)
2 | 3 (Banane - Marlise)
3 | 3 (Orange - Marlise)
....

Nun habe ich eine Variable:
PHP-Code:

$personen '1,2'//Alle Personen von denen ich die Übereinstimmungen möchte 

Als ergebnis hätte ich nun gerne Apfel und Orange

Es wäre super wenn mir da jemand eine gute lösung hätte. Ich hoffe ich konnte es einigermassen gut erklären.

Gruss

Koda

fireweasel 06-07-2015 12:24

Zitat:

Zitat von Koda (Beitrag 671204)
Guten Morgen

Mahlzeit! :D
Zitat:

Zitat von Koda (Beitrag 671204)
Ich habe hier folgende Datenbankstruktur und würde gerne die Überschneidungen finden. Da ich bisher nichts konkretes gefunden habe weiss ich nicht ob es vielleicht sogar mit mysql direkt möglich ist: ...

Ja, ist es.
Zitat:

Da die Datenbankstruktur sehr gross ist habe ich es hier mal etwas abgekürzt und geändert. (...)
Sehr schön. Damit kann man arbeiten.

Zitat:

Nun habe ich eine Variable:
PHP-Code:

$personen '1,2'//Alle Personen von denen ich die Übereinstimmungen möchte 

Als ergebnis hätte ich nun gerne Apfel und Orange
Eigentlich ist das Ganze gar nicht so kompliziert: Du hast zwei Tabellen und willst aus einer davon dein Ergebnis haben. Beide sind über die dritte Tabelle miteinander zu verknüpfen.

(Hinweis: Zu meinem besseren Verständnis habe ich einige Namen leicht abgeändert[0]. Falls sie dir nicht gefallen, musst du sie wieder rückbenennen.)

Wir haben also drei Tabellen:
PHP-Code:

$db = new PDO('sqlite::memory:');
$db->query('create table oebste (ID INTEGER PRIMARY KEY, obst TEXT)');
// ...

$db = new PDO('sqlite::memory:');
$db->query('create table personen (ID INTEGER PRIMARY KEY, person TEXT)');
// ...

$db = new PDO('sqlite::memory:');
$db->query('create table wermagwas (obstID INTEGER REFERENCES oebste, personID INTEGER REFERENCES personen)');
// ... 

Wir brauchen die Spalte "obst" aus der Tabelle "oebste":
PHP-Code:

'select oebste.obst ...' 

Wir benötigen alle drei Tabellen zur Verknüpfung:
PHP-Code:

'... from oebste, personen, wermagwas ...' 

Das erste Auswahlkriterium sind die zwei Primärschlüssel 1 und 2 aus der Tabelle "personen":
PHP-Code:

where personen.ID in (12

Dann sagen wir der Datenbank welche Fremdschlüssel die Verknüpfungstabelle "wermagwas" mit den anderen beiden Tabellen verbinden:
PHP-Code:

... wermagwas.personID personen.pid and wermagwas.obstID oebste.oid 

Das gibt mehrfache Ansammlungen von Früchten gleicher Art. Die beseitigen wir mit "GROUP BY":
PHP-Code:

... group by oebste.obst 

Im Ganzen Satz:
PHP-Code:

$sql 'select oebste.obst
    from oebste, personen, wermagwas
    where
        personen.ID in (1, 2)
        and wermagwas.personID = personen.ID
        and wermagwas.obstID = oebste.ID
    group by
        oebste.obst
    '


... und hier der dazugehörige PHP-Quellcode für PDO und SQLite (für MySQL muss du vermutlich die Spalten-Typen in den "CREATE TABLE"-Statements anpassen):
PHP-Code:

$oebste = array (
    array (
1'Apfel'),
    array (
2'Banane'),
    array (
3'Orange'),
    array (
4'Mandarine'),
);
$personen = array (
    array (
1'Hans'),
    array (
2'Peter'),
    array (
3'Marlise'),
    array (
4'Sandra'),
);
$wermagwas = array (
    array (
11),
    array (
11),
    array (
31),
    array (
12),
    array (
32),
    array (
13),
    array (
23),
    array (
33),
);


$db = new PDO('sqlite::memory:');

$db->query('create table oebste (ID INTEGER PRIMARY KEY, obst TEXT)');
$stmt $db->prepare('insert into oebste values (?, ?)');
foreach (
$oebste as $record) {
    
$stmt->execute(array_values($record));
}
unset (
$stmt);

$db->query('create table personen (ID INTEGER PRIMARY KEY, person TEXT)');
$stmt $db->prepare('insert into personen values(?, ?)');
foreach (
$personen as $record) {
    
$stmt->execute(array_values($record));
}
unset (
$stmt);

$db->query('create table wermagwas (obstID INTEGER REFERENCES oebste, personID INTEGER REFERENCES personen)');
$stmt $db->prepare('insert into wermagwas values (?, ?)');
foreach (
$wermagwas as $record) {
    
$stmt->execute(array_values($record));
}
unset (
$stmt);

// , personen.person, personen.pid // if all relevant columns needed
$sql 'select oebste.obst
    from oebste, personen, wermagwas
    where
        personen.ID in (1, 2)
        and wermagwas.personID = personen.ID
        and wermagwas.obstID = oebste.ID
    group by
        oebste.obst
    '
;

if (!
$stmt $db->prepare($sql)) {
    
Debug::writefln('error: %S %S'$db->errorCode(), $db->errorInfo());
}

$stmt->setFetchMode(PDO::FETCH_ASSOC);

if (!
$stmt->execute()) {
    
Debug::writefln('error: %S %S'$stmt->errorCode(), $stmt->errorInfo());
}

foreach (
$stmt as $idx => $record) {
    
Debug::writefln('row: %S :: %S'$idx$record);
}
Debug::writefln('... end');
exit();

// Debug::writefln() fuer Ausgabe als HTML:
class Debug {
    static function 
writefln() {
        
$args func_get_args();
        
vprintf(
            
strtr(
                
array_shift($args),
                array (
'%S' => '%s')
            ),
            
array_map(
                function (
$var) {
                    if (
is_scalar($var)) {
                        return 
sprintf('<code>%s</code>'htmlspecialchars($var));
                    }
                    
ob_start();
                    
var_dump($var);
                    return 
'<pre>' htmlspecialchars(ob_get_clean()) . '</pre>';
                },
                
$args
            
)
        );
    }


--
[0] "Fruechte" und "Frucht" sind vermutlich brauchbarere Namen. ;)
Siehe auch bei der Konkurrenz:
* Datenbank-Richtlinien - PHP Forum: phpforum.de
* (Sinnvollste) SQL Namenskonventionen - php.de

mermshaus 06-07-2015 14:23

Sinngemäß (nicht getestet) wohl zum Beispiel so:

Code:

SELECT DISTINCT obst.obst
FROM person
LEFT JOIN obst_to_person
ON person.PID = obst_to_person.PID
LEFT JOIN obst
ON obst_to_person.OID = obst.OID
WHERE person.PID IN (1, 2)

(Edit: Oh, hatte das Tab nicht aktualisiert und die andere Antwort nicht gesehen.)

Koda 06-07-2015 20:37

Nabend

Wow. Vielen Dank euch zwei.

Gruss

Koda


Alle Zeitangaben in WEZ +2. Es ist jetzt 13:12 Uhr.

Powered by vBulletin® Version 3.8.2 (Deutsch)
Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0
[c] ebiz-consult GmbH & Co. KG