[NEWSboard IBMi Forum]
  1. #1
    Registriert seit
    Jan 2006
    Beiträge
    112

    SQL Problem / Frage

    Hallo SQL'er,

    habe ein Problem. Gegeben ist nachfolgende Tabellenstruktur:





    Tabelle 1 (MYC4REP):

    C4RCTX, C4D0NB, C4LFDN sind Primärschlüssel

    Tabelle 2 (MYC5REP):

    C5RCTX, C5D0NB, C5LFDN, C5CRNB, C5W3NB, C5W4NB, C5XXTX sind Primärschlüssel

    Tabelle 3 (MWI5REP):

    I5RCTX, I5D0NB, I5CRNB, I5W3NB, I5W4NB, I5XXTX sind Primärschlüssel


    Tabelle 1 stellt einen Kopfsatz dar.
    Tabelle 2 ist die dazugehörige Positionstabelle (Verknüpfung aus Tabelle 1 und 3).
    Tabelle 3 (eigentliche Datentabelle)

    In einer Java Anwendung möchte ich nun folgende Informationen darstellen:

    Aus Tabelle 1:
    C4LFDN und die Bezeichnung (Spalte hinter C4LFDN)

    Aus Tabelle 2:
    Min und Max C5W4NB
    Anzahl der Datensätze aus Tabelle 2 die zu einer Kopfposition C4LFDN gehören

    Aus Tabelle 3:
    Anzahl der Datensätze die als Attribut ein 'J' aufweisen (Spalte I5NFO1 nicht im Screenshot enthalten).


    Beispiel mit C4LFDN = 1
    Darzustellende Informattion:
    1(c4lfdn aus Tabelle 1) ma (text aus Tabelle 1) 1220(min C5W4NB aus Tabelle 2) 1380(max C5W4NB aus Tabelle 2) 4(Anzahl Datensätze aus Tabelle2) 2(Anzahl derer, die in Tabelle 3 ein 'J' aufweisen)


    Soweit bin ich schon gekommen:

    SELECT MYC4REP.*,
    (SELECT MIN(C5W4NB) FROM MYC5REP WHERE C4RCTX = C5RCTX AND C4D0NB = C5D0NB AND C4LFDN = C5LFDN) AS MIN_C5W4NB,
    (SELECT MAX(C5W4NB) FROM MYC5REP WHERE C4RCTX = C5RCTX AND C4D0NB = C5D0NB AND C4LFDN = C5LFDN) AS MAX_C5W4NB,
    (SELECT COUNT(*) FROM MYC5REP WHERE C4RCTX = C5RCTX AND C4D0NB = C5D0NB AND C4LFDN = C5LFDN) AS ANZ_IN_TABELLE_2
    FROM MYC4REP
    WHERE MYC4REP.C4RCTX = '100' AND MYC4REP.C4D0NB = 676 ORDER BY C4RCTX

    mir fehlt nur noch die Anzahl der Datensätze aus Tabelle 3, wo bei I5NFO1 ein 'J' vorhanden ist...

    Wie bekomme ich die da mit rein ?

    Würde mich über eine Hilfe freuen,

    VlG
    Bratmaxxe

  2. #2
    Registriert seit
    Aug 2001
    Beiträge
    2.928
    Hallo,

    zuerst einmal, wenn man mit Sub-Selects arbeitet, sollten man Sub-Selects in der Select-Anweisung wenn möglich vermeiden und lieber in der From-Anweisung einsetzen.

    In Deinem Fall wird die gleiche Abfrage 3x ausgeführt, um den Minimal-Wert, den Maximal-Wert und die Anzahl zu bestimmen. Besser wäre natürlich die Tabelle nur einmalig zu lesen und dabei den Minimal- und Maximal-Wert, sowie die Anzahl ermitteln.

    Weiterhin, muss Du in solchen Fällen die Gesamt-Abfrage zumindest geistig in Einzel-Abfragen zerlegen und anschließend wieder zu einem Großen Ganzen zusammen fassen.

    Soweit ich das überblickt habe werden die folgenden Abfrage benötigt:
    • Tabelle MYC4REP, aus der nur die Sätze mit C4RCTX = '100' und C4D0NB = 676 selectiert werden.
    • Die Tabelle MYC5REP muss für alle Sätze mit C4RCTX = '100' und C5D0NB = 676 (beides Schlüssel-Felder) auf C5rctx, c5d0nb, c5lfdn verdichtet werden. Auf dieser Ebene wird dann der Minimal-Wert und Maximal-Wert, sowie die Anzahl ermittelt.
    • Das Ergebnis aus Abfrage 1 muss mit Tabelle MYC5REP über C5RCTX, C5D0NB, C5LFDN verknüpft werden, da nur MYC5REP über alle Schlüssel-Felder mit Tabelle 3 verknüpft werden kann. Die Verknüpfung der 3 Abfragen muss dann wieder auf RCTX, D0NB und LFDN verdichtet werden und nur die Sätze mit J in INF01 gezählt werden.
    • Die einzelnen Teilergebnisse werden dann miteinander über RCTX, D0NB und LFDN verknüpft und die gewünschten Spalten ausgewählt und wie gewünscht sortiert.


    Die Abfrage könnte im Endeffekt etwa so aussehen:
    PHP-Code:
    With a as (Select 
                  
    from MyC4Rep
                  Where C4RCTX 
    '100' AND C4D0NB 676)
         
    as (Select C5rctxc5d0nbc5lfdn
                      
    Min(C5W4NB) as Min_cw5nb
                      
    Max(C5w4nb) as Max_CW5NB
                      
    Count(*) as Anz_In_Tabelle2
                 from MYC5Rep
                 Where C5RCTX 
    '100' and C5D0NB 676
                 
    Group by c5rctxc5d0nbc5fldn),
         
    as (Select I5RCTXI5D0NBC5LFDN as I5LFDN
                      
    count(I5NF01Anz3
                  from a join MyC5REP on    C4RCTX 
    C5RCTX
                                        
    and C4D0NB C5D0NB
                                        
    and C4LFDN C5LFDN
                         join Tab3    on    C5RCTX 
    I5RCTX 
                                        
    and C5D0NB I5RCTX 
                                        
    and C5CRNB I5CRNB 
                                        
    and C5W3NB I5W3NB 
                                        
    and C5W4NB I5W4NB 
                                        
    and C5XXTX I5XXTX
                  Where I5NF01 
    'J'
    SELECT a.*, Min_Cw5nbMax_Cw5NBAnz_in_Tabelle2Anz3
    FROM   a join b on c4rctx 
    c5rctx and c4d0nb c5d0nb and c4lfdn c5lfdn
             join c on C4rctx 
    i5rctx and c4d0nb i5d0nb and c4lfdn i5lfdn 
    Birgitta
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 5. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  3. #3
    Registriert seit
    Nov 2003
    Beiträge
    2.403
    Also mir ist noch nicht klar, welche Datensätze aus Datei 3 zum Beispiel zu 100/676/1/1220(min)/1380(max)/4(count) gehören.

  4. #4
    Registriert seit
    Jan 2006
    Beiträge
    112
    Zitat Zitat von Pikachu Beitrag anzeigen
    Also mir ist noch nicht klar, welche Datensätze aus Datei 3 zum Beispiel zu 100/676/1/1220(min)/1380(max)/4(count) gehören.
    Hi Pikachu,

    dass sind die Daten aus Tabelle 2...

    Tabelle 2 zu 3 ist eine 1:1 Verknüpfung
    Tabelle 1 zu 2 ist eine 1:n Verknüpfung

    Gruß
    Bratmaxxe

  5. #5
    Registriert seit
    Nov 2003
    Beiträge
    2.403
    Vielleicht so:
    PHP-Code:
    SELECT   C4RCTX,C4D0NB,C4LFDN,C4TEXT,                                 
             
    B.C5CRNB,B.C5W3NB,B.C5W4NB,B.C5XXTX,                         
             
    C5W4NBMIN,C5W4NBMAX,C5COUNT,I5COUNT                          
    FROM     MYC4REP 
    AS A,                                                
             
    MYC5REP AS B,                                                
            (
    SELECT   C5RCTX,C5D0NB,C5LFDN,                               
                      
    MIN(C5W4NB) AS C5W4NBMIN,                           
                      
    MAX(C5W4NB) AS C5W4NBMAX,                           
                      
    COUNT(*)    AS C5COUNT                              
             FROM     MYC5REP                                             
             GROUP BY C5RCTX
    ,C5D0NB,C5LFDN) AS S                          
    LEFT OUTER JOIN                                                       
            
    (SELECT   I5RCTX,I5D0NB,I5CRNB,I5W3NB,I5W4NB,I5XXTX,          
                      
    COUNT(*) AS I5COUNT                                 
             FROM     MYI5REP                                             
             WHERE    I5NFO1
    ='J'                                          
             
    GROUP BY I5RCTX,I5D0NB,I5CRNB,I5W3NB,I5W4NB,I5XXTX) AS I     
    ON       I5RCTX
    =B.C5RCTX AND I5D0NB=B.C5D0NB AND                      
             
    I5CRNB=B.C5CRNB AND I5W3NB=B.C5W3NB AND                      
             
    I5W4NB=B.C5W4NB AND I5XXTX=B.C5XXTX                          
    WHERE    C4RCTX
    =B.C5RCTX AND C4D0NB=B.C5D0NB AND C4LFDN=B.C5LFDN AND  
             
    C4RCTX=S.C5RCTX AND C4D0NB=S.C5D0NB AND C4LFDN=S.C5LFDN 

  6. #6
    Registriert seit
    Jan 2006
    Beiträge
    112
    Hi,

    danke für die Hilfe !

    Die Abfrage von Birgitta habe ich noch etwas angepasst:

    Code:
    With a as (Select *                                           
                  from MyC4Rep                                    
                  Where C4RCTX = '100' AND C4D0NB = 676),         
                                                                  
         b as (Select C5rctx, c5d0nb, c5lfdn,                     
                      Min(C5W4NB) as Min_cw5nb,                   
                      Max(C5w4nb) as Max_CW5NB,                   
                      Count(*) as Anz_In_Tabelle2                 
                 from MYC5Rep                                     
                 Where C5RCTX = '100' and C5D0NB = 676            
              group by c5RCTX, c5D0NB, c5LFDN),                   
                                                                  
    c as (Select I5RCTX, I5D0NB, C5LFDN AS I5LFDN,                
                      count(*) as Anz3                            
                  from a join MyC5REP on    C4RCTX = C5RCTX       
                                        and C4D0NB = C5D0NB       
                                        and C4LFDN = C5LFDN       
     join mwi5rep    on    C5RCTX = I5RCTX                             
                                        and C5D0NB = I5D0NB            
                                        and C5CRNB = I5CRNB            
                                        and C5W3NB = I5W3NB            
                                        and C5W4NB = I5W4NB            
                                        and C5XXTX = I5XXTX            
                  Where I5NFo1 = 'J'                                   
    group by I5RCTX, I5D0NB, C5LFDN )                                  
    SELECT a.*, Min_Cw5nb, Max_Cw5NB, Anz_in_Tabelle2, anz3            
    FROM   a join b on c4rctx = c5rctx and c4d0nb = c5d0nb             
    and c4lfdn = c5lfdn                                                
    join c on C4rctx = i5rctx and c4d0nb = i5d0nb and c4lfdn = i5lfdn  
    Funktioniert tadellos auf der AS400...

    Allerdings nicht für eine mobile Datenbank (H2Databse) - scheinbar wird dieser Syntax nicht unterstützt...

    SQL Grammar

    Wie kann man das dann trotzdem so hinbiegen, dass die H2 den Ausdruck versteht ?

    Gruß
    Bratmaxxe

  7. #7
    Registriert seit
    Feb 2001
    Beiträge
    20.695
    Wenn CTE's und "from (select ...)" nicht unterstützt werden, hilft nur eine Zerlegeung des SQL's oder ggf. eine View-Erstellung mit der dann gejoint wird.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

Similar Threads

  1. SQL Frage
    By Bratmaxxe in forum NEWSboard Programmierung
    Antworten: 4
    Letzter Beitrag: 24-01-07, 19:17
  2. Frage zu SQL UserDefinedFunction
    By cbe in forum IBM i Hauptforum
    Antworten: 4
    Letzter Beitrag: 24-08-06, 17:30
  3. problem mit eigener sql function
    By Stefan_Sk in forum NEWSboard Programmierung
    Antworten: 8
    Letzter Beitrag: 26-05-06, 16:37
  4. SQL Problem
    By Lucky4712 in forum IBM i Hauptforum
    Antworten: 2
    Letzter Beitrag: 24-05-06, 15:57
  5. embedded SQL Performance Problem mit SCROLL
    By itec01 in forum IBM i Hauptforum
    Antworten: 9
    Letzter Beitrag: 16-09-04, 18:38

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • You may not post attachments
  • You may not edit your posts
  •