none
AND und OR mit SelfJoin ? RRS feed

  • Frage

  • Hallo,

    ich brauche dringend eure Hilfe, komme bei meinem Problem einfach nicht weiter.Mir steht in einer Sql Server Compact Datenbank eine Tabelle zur Verfügung. Der Aufbau der Tabelle schaut ungefähr wie folgt aus:

    ID | Number |   Value 

    1   |12345    |     10

    2   |12345    |     20

    3   |12346    |     10

    4   |12346    |     20

    5   |12346    |     30

    Der Benutzer hat nun die Möglichkeit diese Tabelle über eine UI abzufragen. Hierzu kann er die 'Values' aus einer Auswahlliste auswählen. Mehrfachauswahl ist möglich. Ihm stehen also die Werte 10,20,30 zur Verfügung.Das Ergebnis soll mit einem AND oder Alternativ mit einem OR erstellt werden. Eine entsprechende Einstellung kann in der UI gesetzt werden

    Beispiel:

    Der Benutzer wählt die Werte 10 und 20 aus der Auswahlliste aus und setzt den Operator AND.

    Es sollen also alle "Number" angezeigt werden in den der "Value" 10 und 20 ist. In diesem Fall wäre 12345 und 12346.

    Ein einfaches Select * from Table where Value = 10 and Value = 20 funktioniert natürlich nicht.

    Ich bin ratlos, habt ihr eventuell eine Idee ?

    Als Alternative zu Table gibt es auch noch eine Tabelle mit dem Aufbau:

    ID | Number |   Value1 | Value2 | Value 3 

    1   |12345    |     10     |      20

    2   |12346    |     10     |      20    |   30

    Wäre das mit der Tabelle eventuell besser zu lösen ?

    Hoffe ihr habt Ideen !

    DANKE !!!

    Donnerstag, 24. Januar 2013 15:07

Alle Antworten

  • Hallo,

    Reicht als Ergebnis die "Number"? AND Logik geht natürlich wirklich nicht, also OR oder einfacher mit dem IN Operator und einer Auslistung.

    Dann zählst Du die Ergebnissätze und wenn die Anzahl gleich oder größer der Anzahl der ausgewählten Parameterwerte ist, dann passt es. Beispiel mit 10, 20, also 2 Parameterwerte, das überpüfst Du in der HAVING Klausel, ob die Anzahl >= 2 ist.

    SELECT Number, COUNT(*) AS Anz
    FROM DeineTabelle
    WHERE Value IN (10, 20)
    GROUP BY Number
    HAVING COUNT(*) >= 2


    Olaf Helper

    Blog Xing

    Donnerstag, 24. Januar 2013 15:26
  • Das "OR" ist ein einfaches Value IN ( 10, 20, 30 ). Das "AND" ist schwieriger, da es im Grunde ein relationale Division ist:

    DECLARE @Sample TABLE
        (
          ID INT ,
          Number INT ,
          Value INT
        );
    
    INSERT  INTO @Sample
    VALUES  ( 1, 12345, 10 ),
            ( 2, 12345, 20 ),
            ( 3, 12346, 10 ),
            ( 4, 12346, 20 ),
            ( 5, 12346, 30 );
    
    -- OR
    SELECT  DISTINCT
            Number
    FROM    @Sample
    WHERE   Value IN ( 10, 20, 30 );
    
    -- AND
    WITH    Candidates
              AS ( SELECT   Number
                   FROM     @Sample
                   WHERE    Value IN ( 10, 20, 30 )
                 )
        SELECT  Number
        FROM    Candidates
        GROUP BY Number
        HAVING  COUNT(*) = 3;

    Bzw.:

    DECLARE @Filter TABLE ( Value INT );
    INSERT  INTO @Filter
    VALUES  ( 10 ),
            ( 20 ),
            ( 30 );
    
    DECLARE @Sample TABLE
        (
          ID INT ,
          Number INT ,
          Value INT
        );
    
    INSERT  INTO @Sample
    VALUES  ( 1, 12345, 10 ),
            ( 2, 12345, 20 ),
            ( 3, 12346, 10 ),
            ( 4, 12346, 20 ),
            ( 5, 12346, 30 );
    
    -- OR
    SELECT  DISTINCT
            Number
    FROM    @Sample
    WHERE   Value IN ( SELECT   Value
                       FROM     @Filter );
    
    -- AND
    WITH    Candidates
              AS ( SELECT   Number
                   FROM     @Sample
                   WHERE    Value IN ( SELECT   Value
                                       FROM     @Filter )
                 )
        SELECT  Number
        FROM    Candidates
        GROUP BY Number
        HAVING  COUNT(*) = ( SELECT COUNT(*)
                             FROM   @Filter
                           );

    Wichtig für das "AND" ist der Vergleich mit der Anzahl. Hierbei ist die implizite Voraussetzung das (Number, Value) unique ist.





    Donnerstag, 24. Januar 2013 15:31
    Moderator
  • Vielen Dank euch beiden, auf den "Trick" mit der Anzahl bin ich nicht gekommen.

    Das heisst also, dass Having Count(*) = Anzahl der selektierten Values sein muss. Dann müsste es funktionieren :-)

    DANKE !

    Freitag, 25. Januar 2013 07:38