# werte finden die 2 bedingungen erfüllen



## Aenex (3. August 2007)

Hallo Ihr lieben

Ich habe in einer Tabelle Liferscheine eine belegnummer, positionsid und artikelnummer

nun möchte ich mir alle belegnummern anzeigen lassen in denen die positionsid 1 ist und die dazugehörige artikel nummer z.b. 100 ist und positionsid 2 die dazugehörige artikelnummer 200 hat.

wie kann ich das ganze lösen?

das ganze ist eine ms sql datenbank


----------



## lmarkus31 (3. August 2007)

Hallo Aenex,

du kannst die Bedingungen einfach mit "AND"  bzw "OR" verknüpfen und bekommst nur die Datensätze, die alle Bedingungen gleichzeitig erfüllen:


```
SELECT belegnummer
  FROM tabelle
 WHERE (positionsid = 1 AND artilelnummer = 100)
    OR (positionsid = 2 AND artikelnummer = 200)
```

Markus


----------



## Aenex (3. August 2007)

leider gehts so nicht, ich würde es sonst so machen das ich erst die lieferschein raussuche die die erste Bedingung erfüllen und die gefunden dann auf die zweite Bedingung prüfen.

allerdings komm ich mit dem systax nicht ganz klar...

sollte doch ein select im select sein oder?


----------



## lmarkus31 (3. August 2007)

Hallo,

dann hab ich dich falsch verstanden.

Aber wie sollte das ganze denn aussehn? Natürlich kann man SELECTs ineinander schachteln, allerdings frag ich mich, wie die Bedingung aussehen soll:
Entweder ein Datensatz hat die positionsid 100 oder die positionsid 200, oder?

D.h. wenn ich die Datensätze mit der positionsid 100 auslese, dann werde ich innerhalb dieser Datensätze auch keine mehr finden mit der Positionisid 200, es sei denn ich greife mit der gefundenen Belegnummer auf eine andere Tabelle zu, das hast du aber nicht geschrieben.

Beschreibe bitte, welche und wieviel Tabelle involviert sind und wie deren Struktur ist, dann kann man dir weiter helfen.

Markus


----------



## Aenex (5. August 2007)

also es ist nur eine tabelle.

es gibt eine spalte posid und eine spalte artikel die ich abfragen möchte.

ich möchte alle belegnummern anzeigen lassen in denen der lieferschein als erste position eine bestimmte artikelnummer hat und an zweiter stelle auch eine bestimmte artikelnummer.

belegnummer | posid | artikel |
-------------------------------------------- 
34567            | 1       | 12345 |
-------------------------------------------
34567            | 2       | 23555 |

ich hoffe ich hab das einigermassen verständlich erklärt was ich möchte ;-)

Danke für Deine Hilfe


----------



## lmarkus31 (6. August 2007)

Hallo nochmal,

ok, das klingt schon ein wenig anders ;-)

Das was du beschreibst, wäre ein Fall für ein Self Join  bzw. eine Correlated Subquery:

Als Self-Join:

```
select b1.belegnummer 
  from belege b1 inner join belege b2 
 using (belegnummer) 
 where b1.posid=1 
   and b1.artikel=100 
   and b2.posid=2 
   and b2.artikel=200;
```

oder als Correlated Subquery:


```
select belegnummer 
  from belege b1 
 where posid=1 
   and artikel=100 
   and exists 
       (select 1 
          from belege b2 
         where b1.belegnummer = b2.belegnummer 
           and b2.posid=2 
           and b2.artikel=300);
```

Hoffe es hilft,

Markus


----------



## Radhad (6. August 2007)

Der Weg ist zu ineffektiv, mach es eher so:

```
SELECT belegnummer
FROM belege
WHERE posid=1
AND artikel=100
OR posid=2
AND artikel=200;
```


----------



## lmarkus31 (6. August 2007)

Hallo,



> Der Weg ist zu ineffektiv, mach es eher so:



Genau das gleiche Statement gleiche hab ich auch schon gepostet (siehe mein erster Post in dem Thread)..

Leider ist es so, dass dieser Weg falsche Ergebnisse liefert, da es sich bei den gefundenen Einträgen nicht um die selbe Belegnummer handeln muss, d.h. Belegnummer 1234 hat an Position 1 den Artikel 100 und Belegnummer 2345 hat an Position 2 den Artikel 200.. und beide würden angezeigt werden!

Ohne Join / Grouping u.ä. kommt man hier nicht aus, um sicherzustellen, dass es sich um die gleiche Belegnummer handelt.

Markus


----------



## Aenex (6. August 2007)

```
SELECT "BelID" AS "a", "Index", "Artikelnummer", "Index", "Artikelnummer" FROM "OLReweAbf"."dbo"."KHKVKBelegePositionen" WHERE ( ( "Index" = 2 AND "Artikelnummer" IS NULL ) ) GROUP BY "KHKVKBelegePositionen"."BelID", "KHKVKBelegePositionen"."Index", "KHKVKBelegePositionen"."Artikelnummer" HAVING ( ( "Index" = 1 AND "Artikelnummer" = '18088' ) )
```

so sieht die Abfrage aus und gibt mir kein Ergebnis obwohl ich genau weiss das es einen Beleg gibt der an erster Position den artikel 18088 und an zweiter position einen artikel hat wo in artikelnummer nichts drin steht. :-(


----------



## lmarkus31 (6. August 2007)

Hallo nochmal,

hast du dir mal meine beiden Statements angeschaut?

Mit einer kleinen Modifikation bringt dir das Statement genau das Ergebnis, was du möchtest.

Deine zuletzt gepostete Query funktioniert nicht, da die WHERE-Klausel die Resultate schon einschränkt, *bevor* du überhaupt GROUP BY machst. Daher siehst du in dem zu gruppierenden Resultset auch nur die Ergebnisse zu posid=2 und artikel IS NULL.

Innerhalb dieses Resultsets wird er keine Datensätze mit der posid=1 und der angegebenen Artikel-ID finden können, daher findet das HAVING() nichts mehr und die Query liefert gar keine Ergebnisse.

hier mal meine für deinen Fall angepasste Query:


```
SELECT b1.belID  ,b1.artikelnummer
  FROM KHKVKBelegePositionen b1 INNER JOIN KHKVKBelegePositionen b2  
    ON (b1.belID = b2.belID)  
 WHERE b1.index=1  AND b1.artikelnummer=18088
   AND b2.index=2  AND b2.artikelnummer is null;
```

Markus


----------



## Aenex (6. August 2007)

Vielen Dank für die Hilfe allerdings muss ich noch irgendwas falsch machen....

bekomme folgende Fehlermeldung:

[Microsoft][ODBC SQL Server Driver][SQL Server]Das Spaltenpräfix 'b1' stimmt mit keinem in der Abfrage verwendeten Tabellen- oder Aliasnamen überein.


----------



## zeja (6. August 2007)

Hast du wirklich das genaue Statement genommen wie es gepostet ist?

Im From-Teil werden dabei der Tabelle die Aliasnamen b1 und b2 zugewiesen. Das muss dort stehen damit sie später einzeln referenziert werden können.


```
FROM KHKVKBelegePositionen b1 INNER JOIN KHKVKBelegePositionen b2
```

Wenn du das so dort stehen hast und es nich funktioniert dann versuch mal:

```
FROM KHKVKBelegePositionen AS b1 INNER JOIN KHKVKBelegePositionen AS b2
```


----------



## Aenex (6. August 2007)

ja passt alles, ich mach die abfragen mit openoffice und der modliert den ganzen syntax einfach um. so komm ich da nicht weiter hab das ganze jetzt mal im ems sql query gemacht da bekomm ich folgende fehlermeldung "Arithmetischer Überlauffehler beim Konvertieren von numeric in den Datentyp numeric."

kann es eigentlich sein das wenn ich mir einen lieferschein einfach nur mal aufrufe und mir die positionen und dazugehörige artikel anzeigen lasse er mir im feld artikel nichts anzeigt aber trotzdem was drin ist?


----------

