Ankündigung

Einklappen
Keine Ankündigung bisher.

sql bei aufgelisteten Tabellen

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • sql bei aufgelisteten Tabellen

    Liebes Forum

    ich habe eine Datenbank mit drei Tabellen:

    In Tabelle artikel erhalten alle Artikel eine ID:
    Code:
    articleID   Name
    1           Tisch1
    2           Tisch2
    3           Stuhl1
    4           Stuhl2
    In Tabelle optionen werden Optionen definiert, die die Artikel haben können
    Code:
    optionID    option
    10          Holz
    11          Kunststoff
    12          weiß
    13          schwarz
    14          Höhe 70 cm
    15          Höhe 75 cm
    In Tabelle artikel_optionen_relationen werden den Artikeln Optionen zugewiesen
    Code:
    id  articleID optionID
    21    1           10
    22    1           12
    23    1           14
    24    2           10
    25    2           12
    26    2           15
    27    3           10
    28    4           11
    ...
    Tisch1 ist also ein weißer Holztisch mit einer Höhe von 70 cm,
    Tisch2 ein weißer Holztisch mit einer Höhe von 75 cm,
    Stuhl1 ist aus Holz und
    Stuhl2 ist aus Kunststoff.

    Die dritte Tabelle artikel_optionen_relationen macht mir ein bisschen Probleme bei den sql-Abfragen. Wie kann ich zum Beispiel nach Artikeln abfragen, die aus Holz und weiß sind. Das sind in diesem Fall die beiden Tische.

    Liebe Grüße

    Kerstin


  • #2
    Mit WHERE ?! Wie hast du es denn schon versucht?

    [MOD: Verschoben von PHP-Einsteiger]
    The string "()()" is not palindrom but the String "())(" is.

    Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
    PHP.de Wissenssammlung | Kein Support per PN

    Kommentar


    • #3
      Zeige mal was du bereits versucht hast.

      Kommentar


      • #4
        lol. Natürlich mit WHERE

        Wenn ich nur nach einer Option abfragen müsste, wäre es einfach. Das Problem sind die mehreren Optionen, da weiß ich nicht, wie es gehen kann.
        Wenn ich 10 AND 12 nehme, kommt kein Ergebnis. Wenn ich 10 OR 12 nehme, kommen auch Ergebnisse, bei denen nur eine Bedingung erfüllt ist, zum Beispiel auch der Holzstuhl.
        Ich habe keine Idee, wie man hier nach beiden Bedingungen abfragen könnte.

        Liebe Grüße

        Kerstin

        Kommentar


        • #5
          Was für eine DB hast denn Du? Mit PostgreSQL wäre es hier sehr einfach, wenn man die Eigenschaften in einem JSONB-Feld speichert. Ich zeige Dir das mal:

          Code:
          test=*# \d kerstin
                Tabelle »public.kerstin«
              Spalte     |   Typ   | Attribute
          ---------------+---------+-----------
           id            | integer | not null
           name          | text    |
           eigenschaften | jsonb   |
          Indexe:
              "kerstin_pkey" PRIMARY KEY, btree (id)
              "jsonb_index" gin (eigenschaften jsonb_path_ops)
          
          test=*# select * from kerstin ;
           id |  name  |                    eigenschaften                    
          ----+--------+-----------------------------------------------------
            1 | Tisch1 | {"Farbe": "weiß", "Höhe": "70", "material": "Holz"}
            2 | Tisch2 | {"Farbe": "weiß", "Höhe": "75", "material": "Holz"}
            3 | Stuhl1 | {"material": "Holz"}
            4 | Stuhl2 | {"material": "Kunststoff"}
          (4 Zeilen)
          
          test=*# select * from kerstin where eigenschaften @> '{"material": "Holz"}';
           id |  name  |                    eigenschaften                    
          ----+--------+-----------------------------------------------------
            1 | Tisch1 | {"Farbe": "weiß", "Höhe": "70", "material": "Holz"}
            2 | Tisch2 | {"Farbe": "weiß", "Höhe": "75", "material": "Holz"}
            3 | Stuhl1 | {"material": "Holz"}
          (3 Zeilen)
          
          test=*# select * from kerstin where eigenschaften @> '{"material": "Holz", "Höhe": "70"}';
           id |  name  |                    eigenschaften                    
          ----+--------+-----------------------------------------------------
            1 | Tisch1 | {"Farbe": "weiß", "Höhe": "70", "material": "Holz"}
          (1 Zeile)
          
          test=*# select * from kerstin where eigenschaften @> '{"material": "Holz", "Farbe": "weiß"}';
           id |  name  |                    eigenschaften                    
          ----+--------+-----------------------------------------------------
            1 | Tisch1 | {"Farbe": "weiß", "Höhe": "70", "material": "Holz"}
            2 | Tisch2 | {"Farbe": "weiß", "Höhe": "75", "material": "Holz"}
          (2 Zeilen)
          
          test=*#
          Dabei kann hier auch bei Suchabfragen der Index genutzt werden, wie ein Explain zeigt:

          Code:
          test=*# explain select * from kerstin where eigenschaften @> '{"material": "Holz", "Farbe": "weiß"}';
                                                QUERY PLAN                                       
          ---------------------------------------------------------------------------------------
           Bitmap Heap Scan on kerstin  (cost=12.00..16.01 rows=1 width=68)
             Recheck Cond: (eigenschaften @> '{"Farbe": "weiß", "material": "Holz"}'::jsonb)
             ->  Bitmap Index Scan on jsonb_index  (cost=0.00..12.00 rows=1 width=0)
                   Index Cond: (eigenschaften @> '{"Farbe": "weiß", "material": "Holz"}'::jsonb)
          (4 Zeilen)

          Insgesamt bist Du damit sehr flexibel, auch wenn neue Eigenschaften dazukommen.
          PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

          Kommentar


          • #6
            Zeige deinen Code bitte.

            Kommentar


            • #7
              Vielen Dank. PostgreSQL scheint wirklich ganz gut zu sein. Ich kann es aber in diesem Fall nicht nutzen, da es sich um ein cms-System mit fester Datenbank handelt.
              Zeige deinen Code bitte.
              Ich habe dafür noch keinen konkreten Code, weil ich für die Abfrage gar keinen Ansatz habe. Ich habe mit AND und OR probiert, aber das hilft ja nicht weiter.

              Kommentar


              • #8

                Zitat von Kerstin83 Beitrag anzeigen
                Wenn ich 10 AND 12 nehme, kommt kein Ergebnis. Wenn ich 10 OR 12 nehme, kommen auch Ergebnisse, bei denen nur eine Bedingung erfüllt ist, zum Beispiel auch der Holzstuhl.
                Was ja auch auf die eine Tabelle bezogen immer korrekt ist. Ich denke mal das hier dein DB-Design das Problem ist. Du hast in einer Tabelle Optionen (!) ohne weiteres Entscheidungskriterium (Farbe, Größe) und willst dann nach mehreren davon suchen.

                Das widerspricht halt auch der Natur von Optionen:
                Alternative bedeutet die Möglichkeit zur Entscheidung zwischen zwei Optionen oder Dingen. Außerdem bezeichnet der Begriff auch eine einzelne der vorhandenen Möglichkeiten[1] oder eine andere als die bisher fokussierte. Der Begriff wird auch enger definiert, reduziert auf eine Wahl zwischen nur zwei Möglichkeiten, im Sinne einer Entweder-oder-Entscheidung.[
                https://de.wikipedia.org/wiki/Alternative

                Dh laut deinem DB-Design ist es entweder Holz oder Weiß. Dir fehlt noch ein Attributt wie "Material", "Farbe" als zusätzliches Kriterium zum Greifen... WHERE material = holz AND farbe = Weiß

                Ob/wie das in der aktuellen DB-Form funktionieren könnte weiß ich nicht, ev. musst du dann halt auf Basis dessen mit PHP weitermachen.

                Hier dein "Modell" von oben zum Testen, nachdem von dir ja nichts nutzbares kommt .. Falls jemand online damit herumspielen will.. Ist aber "nur" SQLite: https://sqliteonline.com/#fiddle-588...b5613394e77649

                LG
                The string "()()" is not palindrom but the String "())(" is.

                Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
                PHP.de Wissenssammlung | Kein Support per PN

                Kommentar


                • #9
                  Zitat von Kerstin83 Beitrag anzeigen
                  Wenn ich 10 OR 12 nehme, kommen auch Ergebnisse, bei denen nur eine Bedingung erfüllt ist, zum Beispiel auch der Holzstuhl.
                  Der Trick dabei ist, du weißt, dass ein Artikel der zwei Bedingung trifft auch zweimal in dem Ergebnis auftaucht. Filters du danach, hast du deine gewünschten Produkte. Das Filtern geht mit GROUP BY und HAVING. Schaut dann so aus:

                  PHP-Code:
                  SELECT ... FROM ... GROUP BY product_id HAVING COUNT(product_id) = 

                  Kommentar


                  • #10
                    Zitat von Kerstin83 Beitrag anzeigen
                    Vielen Dank. PostgreSQL scheint wirklich ganz gut zu sein. Ich kann es aber in diesem Fall nicht nutzen, da es sich um ein cms-System mit fester Datenbank handelt.
                    Das ist Schade für Dich. Beschäftige Dich mit dem EAV - Modell.
                    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

                    Kommentar


                    • #11
                      Die Datenbank ist nicht von mir, sondern ist so wie sie ist fest vorgegeben.

                      Von der Logik her müsste es doch gehen. Wenn ich mir die Tabelle ansehe, kann ich doch auch die Artikel, die aus Holz und weiß sind raussuchen. Müsste ein Programm dann doch auch können. Also alle Artikel raussuchen, die die Optionen 10 und 12 besitzen.

                      Aber es gibt tatsächlich auch eine solche Tabelle gruppen. Sie ist in dem Beispiel
                      Code:
                      groupID    gruppe
                      71         Material
                      72         Farbe
                      73         Höhe
                      
                      und die Tabelle optionen ist dann
                      
                      optionID    groupID  option
                      10          71       Holz
                      11          71       Kunststoff
                      12          72       weiß
                      13          72       schwarz
                      14          73       Höhe 70 cm
                      15          73       Höhe 75 cm
                      Viele Grüße

                      Kerstin

                      :

                      Kommentar


                      • #12
                        erc Netter "Trick" ... Das wäre ja auch fast wieder so ein Schnipsel den man in die Wissensammlung mitnehmen könnte.. mir kommt vor das war vor kurzem auch schon mal hier.


                        Zitat von Kersint83
                        Wie kann ich zum Beispiel nach Artikeln abfragen, die aus Holz und weiß sind. Das sind in diesem Fall die beiden Tische.
                        SQLite Fiddle: https://sqliteonline.com/#fiddle-588...dceb1815889253
                        Code:
                        SELECT a.name
                        
                        FROM artikel_optionen ao
                        
                        INNER JOIN optionen o ON o.id = ao.option_id
                        INNER JOIN artikel a ON a.id = ao.article_id
                        
                        WHERE o.id = 10 OR o.id = 12
                        
                        GROUP BY name
                        
                        HAVING COUNT(name) > 1
                        Ergebnis:
                        Code:
                        Tisch 1
                        Tisch 2
                        The string "()()" is not palindrom but the String "())(" is.

                        Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
                        PHP.de Wissenssammlung | Kein Support per PN

                        Kommentar


                        • #13
                          vielen Dank, hausl

                          Auf sqliteonline klappt das ja wunderbar. Ich habe es in Access eingesetzt (arbeitet ja auch mit sql), da scheint die Syntax allerdings nicht zu passen. Er kommt mit den beiden JOIN Befehlen nicht zurecht.
                          Du meintest ja auch, dass die JOIN "noch drinnen sind" (diese Bemerkung hast du allerdings gelöscht). Gehts auch ohne Join oder wie meinst du das ?

                          Liebe Grüße

                          Kerstin

                          Kommentar


                          • #14
                            Er kommt mit den beiden JOIN Befehlen nicht zurecht.
                            Was heißt das? Ergebnis falsch? Fehlermeldung? Welche?

                            Ev. so: ?
                            PHP-Code:
                            SELECT a.name

                            FROM artikel a

                            INNER JOIN artikel_optionen ao ON a
                            .id ao.article_id
                            INNER JOIN optionen o ON ao
                            .option_id o.id

                            WHERE o
                            .id 10 OR o.id 12

                            GROUP BY a
                            .name

                            HAVING COUNT
                            (a.name) > 
                            https://sqliteonline.com/#fiddle-588...4f527b5de63455

                            Die Joins brauchst du damit du die Namen der Produkte bekommst. Der Filter basiert ja auf o. , via oa. kommst du dann auf a. wo der Name der beiden drinnen ist, den du schlussendlich ja haben willst. Daher hab ich das auch entfernt, da irrelevant.
                            The string "()()" is not palindrom but the String "())(" is.

                            Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
                            PHP.de Wissenssammlung | Kein Support per PN

                            Kommentar


                            • #15
                              Danke. Es kommt die Fehlermeldung:

                              Syntaxfehler (fehlender Operator) in Abfrageausdruck 'a.id =ao.article_id INNER JOIN optionen o ON ao.option_id = o.i'.

                              Auch in der neuen Version. Access kennt JOIN schon, aber ihm scheint dort etwas zu fehlen...

                              Kommentar

                              Lädt...
                              X