Unterabfrage mit Left Join

Tom_84

Neuer Benutzer
Beiträge
1
Hallo,
ich habe drei Tabellen (Matchcode, Artikel und Adressen). Ziel des ganzen ist es, über eine Abfrage nach Artikelnummer und Adresse zu ermitteln, welche Artikel keinen Eintrag in der Tabelle Matchcode haben.

Matchode.TABELLE
--------------
M_EAN
M_ARTIKEL
M_ADR

Artikel.TABELLE
----------------
AR_NR

Adresse.TABELLE
---------------
AD_NR


Ich habe bereits den LEFT JOIN fertiggestellt - dieser lautet wie folgt:
SELECT
AR_NR ,
M_EAN ,
M_ADR
FROM Artikel.TABELLE
Left Join Matchode.TABELLE on Artikel.TABELLE .AR_NR = Matchode.TABELLE.M_ARTIKEL;

Dadurch bekomme ich schonmal alles angezeigt, was in der Tabelle Matchcode angelegt ist. Über den Left Join auf die Artikeltabelle bekomme ich auch alle Null-Einträge angezeigt. Jetzt würde ich dies einfach gerne erweitern, indem ich eine Unterabfrage einbaue, die mir nach Adresse und Artikelnummer abfragt. Das funktioniert leider noch nicht. Hat jmd. eine Idee?
 
Werbung:

akretschmer

Datenbank-Guru
Beiträge
9.736
Hallo,
ich habe drei Tabellen (Matchcode, Artikel und Adressen). Ziel des ganzen ist es, über eine Abfrage nach Artikelnummer und Adresse zu ermitteln, welche Artikel keinen Eintrag in der Tabelle Matchcode haben.


Dadurch bekomme ich schonmal alles angezeigt, was in der Tabelle Matchcode angelegt ist. Über den Left Join auf die Artikeltabelle bekomme ich auch alle Null-Einträge angezeigt. Jetzt würde ich dies einfach gerne erweitern, indem ich eine Unterabfrage einbaue, die mir nach Adresse und Artikelnummer abfragt. Das funktioniert leider noch nicht. Hat jmd. eine Idee?

Ich versth es nicht ganz. Du suchst, sagst Du zuerst, welche Artikel keinen Eintra in matchcode haben:

Code:
test=*# select * from matchcode ;
      m_ean      | m_artikel | m_adr
-----------------+-----------+-------
 404-060002625-9 |         1 |     2
 404-060002211-4 |         2 |     3
(2 rows)

Time: 0,244 ms
test=*# select * from artikel ;
 ar_nr
-------
     1
     2
     3
(3 rows)

Time: 0,185 ms
test=*# select a.ar_nr, m.m_ean, m.m_artikel from artikel a left join matchcode m on a.ar_nr=m.m_artikel;
 ar_nr |      m_ean      | m_artikel
-------+-----------------+-----------
     1 | 404-060002625-9 |         1
     2 | 404-060002211-4 |         2
     3 |                 |
(3 rows)
test=*# select a.ar_nr, m.m_ean, m.m_artikel from artikel a left join matchcode m on a.ar_nr=m.m_artikel where m.m_artikel is null;
 ar_nr | m_ean | m_artikel
-------+-------+-----------
     3 |       |
(1 row)

Ist es das?
 

akretschmer

Datenbank-Guru
Beiträge
9.736
Grob ja, aber du hast hierbei nicht die Adressen berücksichtigt. Denn ein Artikel kann auch n Adressen beinhalten. Nun möchte ich gerne nach Artikel UND Adresse abfragen.

Dann erklär noch mal Deine Struktur. Ein Artikel (Glas Marmelade im Supermarkt) hat (für mich) erst mal keine Adresse. Auch nicht Supermarkt, denn nach dem Kauf würde die nicht mehr stimmen.

Deine Tabellen hatte ich mir wie folgt aufgebaut:

Code:
test=# create table adresse (ad_nr int primary key);
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "adresse_pkey" for table "adresse"
CREATE TABLE                                                                                     
Time: 30,858 ms                                                                                  
test=*# create table artikel (ar_nr int primary key);
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "artikel_pkey" for table "artikel"
CREATE TABLE                                                                                     
Time: 3,327 ms                                                                                   
test=*# create table matchcode(m_ean ean13, m_artikel int references artikel, m_adr int references adresse);
CREATE TABLE                                                                                                                                   
Time: 48,731 ms

Dabei hatte ich bei matchcode aber schon Bauschmerzen, weil z.B. die EAN an den Artikel gehört.

Andreas
 

akretschmer

Datenbank-Guru
Beiträge
9.736
Hallo Andreas,
der obige Lösungsansatz ist schonmal gut, aber du musst mal die Sicht nicht auf den Supermarkt direkt sehen, sondern auf den direkten Hersteller des Glases Marmelade. Wenn du davon ausgehst, dass du der Hersteller bist, benötigst du für deine unterschiedlichen Kunden, denen du das Glas verkaufst auch unterschiedliche EAN`s. So zum Bsp. kann mein Matchcode für das Glas Marmelade beim Kunden (bzw. Supermarkt) REWE 123 sein, beim Supermarkt von ALDI jedoch 456, bei LIDL 789 usw. Das heisst mein Glas Marmelade kann bei n vielen Adressen hinterlegt sein. Nun hätte ich gerne eine Abfrage, bei der ich die Adressnummer und die Artikel (von / bis) zuvor abfrage und mir dann zurückgegeben wird, wo für diese Artikel für Adresse XY keine EAN-Einträge exisitieren (is NULL).
Im Prinzip müsste das obige Beispiel um die Adresse erweitert werden ;-)
vlt. hast ja noch nen Tipp....?
Gruß
Tom

Okay:

Du hast:
(hab ean mal leer gelassen, wenn für artikel und adresse eine Zeile da ist, dann ist auch die ean definiert, richtig?)

Code:
test=*# select * from match ;
 ean | art | adr
-----+-----+-----
     |   1 |   2
     |   1 |   3
     |   2 |   3
     |   3 |   3
     |   3 |   2
(5 rows)

Time: 0,158 ms
test=*# select * from artikel ;
 i
---
 1
 2
 3
(3 rows)

Time: 0,166 ms
test=*# select * from adresse ;
 i
---
 3
 2
 1
(3 rows)

Du suchst jetzt die Kombinationen von artikel und adresse, die es in der match-Tabelle nicht gibt, richtig?

Code:
test=*# select a.i as art, d.i as adr from artikel a cross join adresse d except select art, adr from match;
 art | adr
-----+-----
   1 |   1
   2 |   2
   3 |   1
   2 |   1
(4 rows)

Achtung, Cross-Join, da noch die Adress-Nummer und Artikel in das WHERE mit einbauen, damit das nicht detoniert.
 

akretschmer

Datenbank-Guru
Beiträge
9.736
Danke vorab Andreas, aber es fehlt leider noch eine Kleinigkeit ;) .

Mag sein. Aber es ist mit der Zeit anstrengend, Dir zu helfen, da Deine Tabellen sich vom Namen ändern, die Ausgaben nicht zum Select passen etc. Mal ist es EAN, dann M_EAN oder auch GTIN. Vielleicht zeigst einfach mal ein Beispiel (komplett), wo man Dein Problem nachvollziehen kann.
 

akretschmer

Datenbank-Guru
Beiträge
9.736
select
S12_NR AS Artikelnr,
S20_ADR_NR AS ADRESSE,
S20_EAN_NR AS EAN
from sy0012_00108 Left Join Sy0020_00108
on sy0012_00108.S12_NR = SY0020_00108.S20_ART_NR where
s12_NR >=#INPUT ("numeric", "Artikel von", "0")
and s12_NR <=#INPUT ("numeric", "Artikel bis", "999999999") and
S20_EAN_NR is Null;

Es werden mir zwar die Artikel ohne EAN-Eintrag ausgegeben, allerdings geht mir hier der Adressbezug flöten. Sprich ich kann die Bedingung nicht noch um die Adresse erweitern.

ich sehe nicht, daß eine Erweiterung der Abfrage im WHERE-Teil um " ... and S20_ADR_NR between X and Y ..." nicht gehen sollte.
 
Werbung:

akretschmer

Datenbank-Guru
Beiträge
9.736
Genau so seh ich das auch, es geht aber leider so nicht ;-)

Weder bei von / bis Selektion noch bei sonstiger Adresse bei der ich definitv Einträge in der Tabelle Matchcode habe, bekomme ich Werte zurück. Im unteren Bsp. habe ich die Adresse 0 selektiert bei der sehr viele Einträge existieren, egal welche Adresse ich selektiere, ich erhalte kein Ergebnis.

Wilde Vermutung: nicht passende Datentypen.
 
Oben