hawkmaster: SELECT MIN() bringt mehrere Werte zurück

Hallo zusammen,
Es gibt folgende Tabellen
Tabelle serviceproperty
----------------------------------------------------
ServicePropertyID ServiceID ServiceProperty
10                      3               blau
6                       2               blabla
1                       1               Amex
14                      4               oben
15                      4               links
16                      4               rechts
4                       1               Visa

Tabelle productservice
-----------------------------------------------------------
ServicePropertyID,ProductID
10                2
6                 2
1                 2
14                2
15                2
16                2
4                 2

Mit dieser Abfrage:

  
SELECT A.ServiceID  
FROM serviceproperty A  
JOIN productservice B ON B.ServicePropertyID = A.ServicePropertyID  
WHERE B.ProductID = 2  
GROUP BY A.ServiceID  
ORDER BY A.ServiceID ASC  

bekomme ich zurück:
ServiceID
-------------
1
2
3
4

Ich möchte aber nur die kleinste ServiceID haben, also nur 1
Wenn ich zusätzlich noch "LIMIT 1" einbaue geht das. Ich würde es aber gerne ohne "Limit" machen. Wenn ich es versuche mit SELECT MIN(A.ServiceID) bekomme ich ebenso alle 4 Einträge zurück.

Wie kann man dies optimieren?

vielen Dank und viele Grüße
hawk

  1. Hi,

    Es gibt folgende Tabellen
    Tabelle serviceproperty

    ServicePropertyID ServiceID ServiceProperty
    10                      3               blau
    6                       2               blabla
    1                       1               Amex
    14                      4               oben
    15                      4               links
    16                      4               rechts
    4                       1               Visa

    Tabelle productservice

    ServicePropertyID,ProductID
    10                2
    6                 2
    1                 2
    14                2
    15                2
    16                2
    4                 2

    Mit dieser Abfrage:

    SELECT A.ServiceID
    FROM serviceproperty A
    JOIN productservice B ON B.ServicePropertyID = A.ServicePropertyID
    WHERE B.ProductID = 2
    GROUP BY A.ServiceID
    ORDER BY A.ServiceID ASC

      
    Der JOIN liefert also alle Datensätze aus der ersten Tabelle zurück, weil es für B.ProductID = 2 zu jeder ServicePropertyID aus B auch eine gleiche in A gibt.  
      
    
    > bekomme ich zurück:  
    > ServiceID  
    > -------------  
    > 1  
    > 2  
    > 3  
    > 4  
      
    Und was wundert dich daran? Schließlich hast du nach A.ServiceID gruppiert.  
      
    
    > Ich möchte aber nur die kleinste ServiceID haben, also nur 1  
      
    Dann willst du vielleicht \*nicht\* nach der ServiceID gruppieren?  
      
    MfG ChrisB  
      
    
    -- 
    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
    
    1. Hallo ChrisB,
      danke für deine Hilfe.

      Dann willst du vielleicht *nicht* nach der ServiceID gruppieren?

      hmm, vielleicht steht mir auch einer auf der Leitung aber wonach sonst?
      Ich hatte auch schon versucht einen zusätzlichen JOIN mit Tabelle "service"
      und dann hier eine Gruppierung auf die ServiceID. Brachte aber auch nichts.

      vielen Dank und viele Grüße
      hawk

      1. Hallo,

        schreibe doch zuerst mal eine Abfrage für MIN(ServiceId) gruppiert bei ProduktID. Dann sehen wir weiter. Vielleicht geht der, der grad auf dem Schlauch steht dann von ganz allein runter.

        Cheers, Frank

        1. Hallo zusammen,

          schreibe doch zuerst mal eine Abfrage für MIN(ServiceId) gruppiert bei ProduktID. Dann sehen wir weiter. Vielleicht geht der, der grad auf dem Schlauch steht dann von ganz allein runter.

          hmm, ich kann doch aber nicht nach der ProductID gruppieren?
          So bekomme ich schon nur eine Zeile zurück aber das geht dann auch ohne MIN()

            
          SELECT A.ServiceID  
          FROM serviceproperty A  
          JOIN productservice B ON B.ServicePropertyID = A.ServicePropertyID  
          WHERE B.ProductID = 2  
          GROUP BY B.ProductID  
          ORDER BY A.ServiceID ASC  
          
          

          vielen Dank und viele Grüße
          hawk

          1. Hallo, mein Vorschlag hier, das war ja auch nur der erste Schritt. :-) Cheers

          2. moin,

            SELECT A.ServiceID
            FROM serviceproperty A
            JOIN productservice B ON B.ServicePropertyID = A.ServicePropertyID
            WHERE B.ProductID = 2
            GROUP BY B.ProductID
            ORDER BY A.ServiceID ASC

              
            dieser code ist aber blödsinn und funktioniert auch nur  unter mysql. jedes andere dbms  würde dir dabei eine fehkermeldung ausgeben. was du letztlich willst ist eine unterabfrage auf exists und die MIN aggregationsfunktion. alles andere wäre wohl ein schlechter weg.  
              
            Ilja
            
            1. Hallo Ilja,

              vielen Dank für deine Hilfe.

              »»was du letztlich willst ist eine unterabfrage auf exists und die MIN aggregationsfunktion.

              ohje, ich glaube das verstehe ich nicht ganz.

              vielen Dank und viele Grüße
              hawk

              1. moin,

                ohje, ich glaube das verstehe ich nicht ganz.

                was du willst ist das:

                SELECT MIN(A.ServiceID) KleinsteServiceID
                FROM serviceproperty A
                WHERE EXISTS (SELECT NULL
                              FROM productservice B
                              WHERE B.ServicePropertyID = A.ServicePropertyID
                              AND B.ProductID = 2
                             )
                ;

                du siehst,keine gruppierung notwending, eine korrlierte unterabfrage auf EXISTS,dieMIN funktion und aus die maus.....

                Ilja

                1. Hallo Ilja,

                  du siehst,keine gruppierung notwending, eine korrlierte unterabfrage auf EXISTS,dieMIN funktion und aus die maus.

                  Oh mann, eigentlich so einfach wenn man weiss wie :-)
                  Das mit dem Unterabfragen und Exists war / ist mir einfach noch nicht so geläufig.

                  Klasse, wieder viel gelernt.
                  Ganz herzlichen Dank

                  vielen Dank und viele Grüße
                  hawk

      2. Hallo ChrisB,

        ich weiss nicht ob du nochmals in den Post reinschaust.

        Dann willst du vielleicht *nicht* nach der ServiceID gruppieren?

        Meintest du man soll nach ProductID gruppieren?

        vielen Dank und viele Grüße
        hawk

        1. Hi,

          Dann willst du vielleicht *nicht* nach der ServiceID gruppieren?

          Meintest du man soll nach ProductID gruppieren?

          Das kommt darauf an, was genau du mit dem Statement erreichen willst.

          Wenn du wirklich nur die Datensätze für ProductID = 2 haben willst, dann kannst du dir das gruppieren auch sparen.

          MfG ChrisB

          --
          RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
  2. Hallo Hawkmaster,

    du benötigst dafür eher eine "korrelierende" Unterabfrage à la

    WHERE a.ServiceID = (Gib mir die kleinste 'ServiceID' aus 'serviceproperty' für die in 'productservice' die 'ProductID' gleich 2 bzw. gleich der 'ProductID' aus der umgebenden Abfrage ist)

    Alternativ möglich vielleicht auch je nach Datenbanksystem, erstelle eine View
    Gib mir die kleinste ServiceID pro Produkt und benutze sie in einem INNER JOIN über die ProduktID und ServiceID

    Cheers, Frank

    1. Hallo Frank,
      vielen Dank für deine Hinweise und Tipps.

      du benötigst dafür eher eine "korrelierende" Unterabfrage à la

      Ich habe nun mal was versucht. Es kommt tatsächlich nur eine Row zurück mit der kleinsten Service ID. Bin mir aber nicht so sicher ob das so korrekt ist?

        
      SELECT A.ServiceID  
      FROM serviceproperty A  
      WHERE A.ServiceID = (SELECT MIN(ServiceID) FROM serviceproperty C JOIN productservice B ON B.ServicePropertyID = C.ServicePropertyID WHERE B.ProductID = 2)  
      GROUP BY A.ServiceID  
      ORDER BY A.ServiceID ASC  
      
      

      vielen Dank und viele Grüße
      hawk