2016-10-17 2 views
1

Ich arbeite in IBExpert eine vorhandene Abfrage ändern. Normalerweise führen wir diese Abfrage aus, exportieren die Ergebnisse nach Excel und führen dann ein Makro aus, um ein neues Feld zu erstellen - ich versuche, den Schritt in Excel zu eliminieren.Mit SQL 1-zu-1-Datensätze vs viele-zu-viele identifizieren

Wir haben zwei Schlüsselfelder aus verschiedenen Tabellen - nennen wir sie ProjNo aus Projekten und CustNo aus Kunden -, die eine Viele-zu-Viele-Beziehung haben. Ein Projekt kann mehrere Kunden umfassen und ein Kunde kann mehrere Projekte ausführen. Zwischen ihnen befindet sich eine Verknüpfungstabelle, um die Beziehung zu verwalten.

Wir wollen identifizieren, wo es eine 1: 1-Korrelation zwischen diesen Werten gibt, wo ein ProjNo nur einmal erscheint und ein CustNo nur einmal erscheint. Ich habe ziemlich viel herumgefummelt und versucht, eine Case-When-Aussage zusammenzustellen, aber ich habe nicht viel Glück. Hier ist mein letzter Versuch:

(case when (select count(Proj.ProjNo) PCounts from Proj group by Proj.ProjNo)=1 and 
      (select count(Cust.CustNo) CCounts from Cust group by Cust.CustNo)=1 
     then "1:1" else "Multi" end) as Links 

Ich weiß, ich werde eine Art von Where-Klausel enthalten müssen, die nur Werte überprüft, die die PROJNR in dem Hauptkörper der Abfrage übereinstimmen, aber ich bin nicht sicher, ob ich Ich bin sogar in die richtige Richtung oder wie ich die SQL-Anweisungen innerhalb der Fall mit der Hauptabfrage verbinden würde.

Hilfe?

Antwort

1

Das war kniffliger als es irgendein Recht zu sein. Der Join mit drei Tabellen hat mich dazu gebracht, Cust and Link und dann Proj und Link beizutreten, und schließe mich dann diesen Ergebnissen an. Der Trick dabei ist, dass Sie, sobald Sie einem der Tabellenpaare beitreten, es nicht für das andere Paar tun müssen, sondern nur die letzte Tabelle mit dem verknüpften Paar verknüpfen. Das klingt ungefähr so ​​verwirrend wie ich es gefunden habe.

Also hier ist die Drei-Wege-Join, die ich kam.

SELECT cnc.cust_tot, pn_link.CustNo, pn_link.ProjNo, pn_link.proj_tot 
FROM 
    (SELECT CustNo, Count(CustNo) as cust_tot 
    FROM Cust 
    GROUP BY CustNo) as cnc 
INNER JOIN 
    (SELECT a.CustNo, a.ProjNo, b.proj_tot 
    FROM 
    Link as a 
    INNER JOIN 
     (SELECT ProjNo, Count(ProgNo) as proj_tot 
     FROM Proj 
     GROUP BY ProjNo) as b 
    ON a.ProjNo = b.ProjNo) as pn_link 
ON cnc.CustNo = pn_link.CustNo 
WHERE cnc.cust_tot = 1 
and pn_link.proj_tot = 1 

Am Ende habe ich die WHERE Aussage nur die Spiele eins-zu-eins zu greifen. Um die Multi-Matches es nur

ändern
WHERE cnc.cust_tot > 1 
or pn_link.proj_tot > 1 

können Sie dann UNION die beiden Anfragen zu bekommen es alle in einer Tabelle wieder. Wütend.

+0

Vielen Dank! Ich muss eine kleine Änderung vornehmen, um es anzupassen, aber es sieht so aus, als ob es mich dazu bringen sollte, was ich brauche. – Werrf