1. Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm
    Information ausblenden

Suche alle Rezepte die ich mit meinem Bestand kochen kann.

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von patrickm, 19 Dezember 2019.

  1. patrickm

    patrickm Neuer Benutzer

    Hallo Zusammen,

    ich möchte mir gern alle Rezepte anzeigen lassen, die ich mit meinem Bestand kochen kann. Dafür habe ich 4 Tabellen erstellt (rezepte, zutaten, rezepte_zutaten, bestand) und habe die zu einer verknüpft.

    Das habe ich wie folgt gemacht:

    SELECT r.name, rz.benoetigte_zutaten, rz.primaere_zutaten, z.zutaten_name, b.zutaten_bestand
    FROM rezepte r
    JOIN rezepte_zutaten rz ON r.rid = rz.rid
    JOIN zutaten z ON z.zid = rz.zid
    JOIN bestand b ON b.zid = z.zid

    Somit habe ich nun alle informationen die ich miteinander vergleichen kann. Aber irgendwie habe ich das Gefühl, dass was ich vor habe, wird mit SQL nicht funktionieren. Aber zurück zu meinem Problem. Naja, eigentlich fängt mein Problem hier schon an. Ich weiß nicht wie ich anfangen soll. Erreichen möchte ich, wenn ich z.B die primären Zutaten Eier und Mehl zu Hause habe, dass mir das Waffelrezept angezeigt wird.

    Ich hoffe ihr könnt mir helfen und Licht ins dunkle bringen.

    Grüße
    Patrick
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Code:
    test=*# select * from rezepte;
     id |  name  
    ----+--------
      1 | Waffel
      2 | Bier
      3 | Steak
    (3 rows)
    
    test=*# select * from zutaten;
     id |  name   
    ----+---------
      1 | Wasser
      2 | Salz
      3 | Pfeffer
      4 | Eier
      5 | Mehl
    (5 rows)
    
    test=*# select * from bestand;
     id | zutat | menge
    ----+-------+-------
      1 |     4 |    10
      2 |     5 |    10
    (2 rows)
    
    test=*# select * from rezepte_zutaten;
     id | rezept | zutat
    ----+--------+-------
      1 |      1 |     4
      2 |      1 |     5
      3 |      3 |     2
      4 |      3 |     3
    (4 rows)
    
    test=*# with bestand as (select rz.rezept, array_agg(b.zutat) as vorhanden from rezepte_zutaten rz left join bestand b on rz.zutat = b.zutat where b.menge > 0 group by rz.rezept), rezepte as (select name, array_agg(zutat) as benötigt from rezepte_zutaten rz left join rezepte on rz.rezept=rezepte.id group by name) select rezepte.* from rezepte, bestand where vorhanden @> benötigt;
      name  | benötigt
    --------+----------
     Waffel | {4,5}
    (1 row)
    
    test=*#
    
    Allerdings ist das PostgreSQL und ich nutze Arrays, außerdem habe ich jetzt auf die Namen der Zutaten und eine Mengenangabe / prüfung im Rezept / Bestand verzichtet.
     
  3. patrickm

    patrickm Neuer Benutzer

    Hallo akretschmer,

    erstmal vielen Dank für die schnelle Antwort. Und dann muss ich noch zugeben, dass der Beitrag eigentlich in "MySQL und MariaDB" gehört. Da habe ich wohl beim anlegen gestern gepennt, sorry. Ich habe mal Deinen Vorschlag nachgebaut und bekomme aber leider in der Command Line einen Fehler in der SQL-Syntax: 'bestand as (select rz.rezept, array_agg(b.zutat) as vorhanden from rezepte_zutat'. Vermutlich liegt es daran, dass ich eine MySQL Datenbank habe. Ich muss noch dazu sagen, dass ich kein Datenbank Experte bin. Aber soll ja auch nur für zu Hause sein. :)

    Den Namen der Zutaten finde ich bei der Abfrage gar nicht so wichtig, aber ohne Prüfung der Mengangaben im Rezpt <-> Bestand würde ich doch auch Rezepte angezeigt bekommen, die ich gar nicht kochen kann.

    Viele Grüße
    Patrick
     
  4. castorp

    castorp Datenbank-Guru

    Statt array_agg() könntest Du in MySQL group_concat() nehmen um die Zutaten zu einer Liste zu "aggregieren"
     
  5. patrickm

    patrickm Neuer Benutzer

    Hallo castorp,

    ich habe es mal mit group_concat() ausprobiert, aber leider werden dann die benötigten Zutatenmengen falsch dargestellt.

    Hier mal der Code, um besser nachvollziehen zu können, was passiert:

    Code:
    DROP SCHEMA IF EXISTS test;
    CREATE SCHEMA test;
    USE test;
    
    CREATE TABLE zutaten (
    zid int AUTO_INCREMENT PRIMARY KEY,
    name nvarchar(50)
    )ENGINE=INNODB;
    
    CREATE TABLE bestand (
    bid int AUTO_INCREMENT PRIMARY KEY,
    zid int,
    bestand int UNSIGNED
    )ENGINE=INNODB;
    
    CREATE TABLE rezepte (
    rid int AUTO_INCREMENT PRIMARY KEY,
    rezeptname nvarchar(50)
    )ENGINE=INNODB;
    
    CREATE TABLE rezepte_zutaten(
    rzid int AUTO_INCREMENT PRIMARY KEY,
    rid int,
    zid int,
    zutatenmenge int,
    Foreign key (rid) REFERENCES rezepte (rid) ON DELETE CASCADE
    )ENGINE=INNODB;
    
    INSERT INTO zutaten VALUES (1, 'Wasser');
    INSERT INTO zutaten VALUES (2, 'Salz');
    INSERT INTO zutaten VALUES (3, 'Pfeffer');
    INSERT INTO zutaten VALUES (4, 'Eier');
    INSERT INTO zutaten VALUES (5, 'Mehl');
    
    INSERT INTO bestand VALUES (1, 4, 2);
    INSERT INTO bestand VALUES (2, 5, 0);
    
    INSERT INTO rezepte VALUES (1, 'Waffel');
    INSERT INTO rezepte VALUES (2, 'Bier');
    INSERT INTO rezepte VALUES (3, 'Steak');
    
    INSERT INTO rezepte_zutaten VALUES (1, 1, 4, 1);
    INSERT INTO rezepte_zutaten VALUES (2, 1, 5, 1);
    INSERT INTO rezepte_zutaten VALUES (3, 3, 2, 1);
    INSERT INTO rezepte_zutaten VALUES (4, 3, 3, 1);
    
    SELECT * FROM rezepte;
    SELECT * FROM zutaten;
    SELECT * FROM bestand;
    SELECT * FROM rezepte_zutaten;
    
    SELECT r.rezeptname, z.name, b.bestand, rz.zutatenmenge FROM rezepte r JOIN rezepte_zutaten rz ON r.rid = rz.rid JOIN zutaten z ON z.zid = rz.zid JOIN bestand b ON b.zid = z.zid;
    
    SELECT r.rezeptname, GROUP_CONCAT(z.name) AS zutaten, b.bestand, rz.zutatenmenge FROM rezepte r JOIN rezepte_zutaten rz ON r.rid = rz.rid JOIN zutaten z ON z.zid = rz.zid JOIN bestand b ON b.zid = z.zid;
    
    
    Wichitg ist mir halt die Abfrage Bestand >= Benötigte Menge

    Grüße
    Patrick
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden