SAS9

Wie man zwei Tabellen ohne gemeinsamen Schlüssel verknüpft

Simon 5 Aufrufe

Es kommt in der SAS©-Programmierung häufig vor, dass zwei Datensätze miteinander verknüpft werden müssen. Normalerweise verwenden wir eine MERGE-Anweisung in einem DATA-Schritt oder einen LEFT/INNER JOIN in SQL über einen gemeinsamen Schlüssel (z. B. eine Kunden-ID).

Aber was tun, wenn beide Tabellen keine gemeinsamen Variablen haben und die Verknüpfung von komplexen Bedingungen abhängt, wie z.B. Werten, die in bestimmten Intervallen liegen? Dies wird als ungleiche Verknüpfung (Non-Equi Join) bezeichnet.

Betrachten wir einen praktischen Fall aus einer Benutzerdiskussion, um zu verstehen, wie dieses Problem elegant mit PROC SQL gelöst werden kann.

Die vermeintlich gute Idee: Die Schleife im DATA-Schritt

Angesichts dieses Problems ist die erste Intuition oft, einen iterativen Ansatz über einen DATA-Schritt zu versuchen. Die Idee wäre, eine Zeile aus der Tabelle accounts zu lesen und dann die gesamte Tabelle intervals zu durchlaufen, um eine Übereinstimmung zu finden.

Obwohl technisch möglich, ist dieser Ansatz in SAS© komplex zu programmieren:

  • Er erfordert die Manipulation von zwei Lesepointer.

  • Es muss das Zurücksetzen des Lesevorgangs der Tabelle intervals für jedes Konto verwaltet werden (was die Option POINT= oder mehrere SET-Anweisungen erfordern kann).

  • Der Code wird schnell unübersichtlich und schwer zu warten.

Wie ein Mitwirkender in der Diskussion betont: "Ich würde keine Zeit mit einer Schleifenmethodik verschwenden."

Die elegante Lösung: PROC SQL und das Kartesische Produkt


Die effektivste und lesbarste Lösung liegt in der Verwendung von PROC SQL. Im Gegensatz zum DATA-Schritt ist SQL dazu konzipiert, komplexe Beziehungen zwischen Mengen auf natürliche Weise zu verwalten, ohne sich um die Sortierreihenfolge oder explizite Schleifen kümmern zu müssen.

Der Trick besteht darin, eine kartesische Verknüpfung (alle Zeilen von A kombiniert mit allen Zeilen von B) durchzuführen und das Ergebnis sofort zu filtern.


Note :
So lösen Sie das Problem in wenigen Zeilen:
1PROC SQL;
2 CREATE TABLE DATA3 AS
3 SELECT
4 t1.grpnm,
5 t2.acct,
6 t2.bal1,
7 t2.bal2
8 FROM
9 intervals t1, /* Table 1 */
10 accounts t2 /* Table 2 */
11 WHERE
12 /* Condition pour le premier solde */
13 t2.bal1 BETWEEN t1.min1 AND t1.max1
14 AND
15 /* Condition pour le second solde */
16 t2.bal2 BETWEEN t1.min2 AND t1.max2;
17QUIT;
Warum funktioniert das?
FROM data1, data2: Indem man die beiden Tabellen durch ein Komma trennt, ohne eine explizite JOIN-Klausel (wie LEFT JOIN) anzugeben, bereitet SAS© implizit ein kartesisches Produkt vor. Es vergleicht virtuell jede Zeile der Tabelle intervals mit jeder Zeile der Tabelle accounts.

WHERE ... BETWEEN: Hier geschieht die Magie. Anstatt eine Gleichheit (ON t1.id = t2.id) zu verwenden, nutzen wir logische Operatoren (BETWEEN, >, <). SQL behält nur die Kombinationen bei, bei denen die Zahlen in die richtigen "Kästen" fallen.

Wenn Sie bei dem Versuch, eine komplexe Schleife in einem DATA-Schritt zu erstellen, weil Sie keinen gemeinsamen Schlüssel haben, stecken bleiben: denken Sie an SQL.

Lassen Sie sich nicht von der Vorstellung einschränken, dass ein Join eine identische Spalte erfordert. Solange Sie eine logische Regel definieren können (wie "zwischen X und Y liegen"), kann PROC SQL die Arbeit viel prägnanter erledigen.