2017-11-12 2 views
0

Es gibt ein Projekt, das ich arbeiten muss, die Haupttransaktionstabelle und einige Untertransaktionstabellen namens Provider. Jeder Anbieter hat eine eigene Tabelle. Die Haupttabelle speichert nur den Betrag (wie auch die Untertabelle), das Datum und einige wichtige Daten, auch die Referenz-ID der Untertabelle. Ich möchte Sub Tabellen basierend auf Anbieter ID zu verbinden. Wenn die Dinge unordentlich werden können, kann ich Tabellennamen als assoziatives Array behalten. Was mich verwirrt, ist, dass die Tabelle jedes Anbieters einen anderen Primärschlüsselnamen hat.Beitreten mehr als 2 Tabellen basierend auf Wert in Mysql

Provider-Tabellen sind ziemlich identisch mit Ausnahme einiger Spalten. Was ich wirklich versuche zu erreichen, ist eine Suche in allen diesen 3 Tabellen als eine.

Eine andere Frage, ist dies eine dumme Idee, wenn ja, welcher Ansatz besser wäre? Tägliche 400-500 Datensätze werden erwartet. Beachten Sie, dass in Zukunft weitere Provider-Tabellen hinzugefügt werden können. Diese Struktur wurde von jemandem entwickelt, der erfahrener ist als ich. Ich konnte niemanden davon überzeugen, dass das schlecht ist.

Transaction 
+-----+-----+-----+-----+ 
| id | ref | prv | date| 
+-----+-----+-----+-----+ 
| 1 | 4 | 2 | .. | 
+-----+-----+-----+-----+ 
| 2 | 4 | 3 | .. | 
+-----+-----+-----+-----+ 
| 3 | 5 | 2 | .. | 
+-----+-----+-----+-----+ 
| 4 | 7 | 1 | .. | 
+-----+-----+-----+-----+ 
| 5 | 22 | 3 | .. | 
+-----+-----+-----+-----+ 

Providers (prv value) 
+-----+---------------+-----+ 
| pID | providerName | .. | 
+-----+---------------+-----+ 
| 1 | providerA  | .. | 
+-----+---------------+-----+ 
| 2 | providerB  | .. | 
+-----+---------------+-----+ 
| 3 | providerC  | .. | 
+-----+---------------+-----+ 

p_providerA (ref value) 
+-----+--------+------+-----+ 
| aID | amount | name | .. | 
+-----+--------+------+-----+ 
| 1 | 90.20 | alf | .. | 
+-----+--------+------+-----+ 
| 2 | 70.00 |willie| .. | 
+-----+--------+------+-----+ 
| 3 | 43.10 | kate | .. | 
+-----+--------+------+-----+ 


p_providerB (ref value) 
+-----+--------+------+-----+ 
| bID | amount | name | .. | 
+-----+--------+------+-----+ 
| 3 | 65.20 | jane | .. | 
+-----+--------+------+-----+ 
| 4 | 72.00 | al | .. | 
+-----+--------+------+-----+ 
| 5 | 84.10 | bundy| .. | 
+-----+--------+------+-----+ 


p_providerC (ref value) 
+-----+--------+------+-----+ 
| bID | amount | name | .. | 
+-----+--------+------+-----+ 
| 3 | 10.20 | mike | .. | 
+-----+--------+------+-----+ 
| 4 | 40.00 | kitt | .. | 
+-----+--------+------+-----+ 
| 6 | 27.60 | devon| .. | 
+-----+--------+------+-----+ 

Erwartetes Ergebnis

+-----+-----+-----+-----+----+--------+------+-----+ 
| id | ref | prv | date| |  |  |  | 
+-----+-----+-----+-----+----+--------+------+-----+ 
| 1 | 4 | 2 | .. | 4 | 72.00 | al | .. | (from prv. b) 
+-----+-----+-----+-----+----+--------+------+-----+ 
| 2 | 4 | 3 | .. | 4 | 40.00 | kitt | .. | (from prv. c) 
+-----+-----+-----+-----+----+--------+------+-----+ 
+0

Wissen Sie, dass jeder Anbieter eine andere Tabelle hat? – scaisEdge

+0

fügen Sie bitte Beziehungen zwischen Tabellen hinzu. wie, Anbieter [einer zu vielen] Subprovider. 'transaction [viele zu viele] Provider ' die nicht intuitive Art der Benennung ist zu vermeiden, die Frage zu folgen -)) – marmeladze

+0

Ja, jeder Anbieter behält seine eigenen Transaktionsdaten, und man behält Referenzen zu diesen. – siniradam

Antwort

1

der aktuelle Tabellenentwurf gegeben, eine der Möglichkeiten, um das gewünschte Ergebnis zu erhalten ist, zu „brechen“ die Tabelle Transaktion in separate Abfragen und kombiniert den mit einer UNION ALLE

Die Zeilen aus Transaction Tabelle könnte wie folgt zurückgegeben:

SELECT t.* FROM Transaction t WHERE t.prv = 1 
UNION ALL 
SELECT t.* FROM Transaction t WHERE t.prv = 2 
UNION ALL 
SELECT t.* FROM Transaction t WHERE t.prv = 3 
UNION ALL 
... 

nun jede dieser SELECT kann ein an die entsprechenden Anbieter Tabelle

SELECT t.*, pa.amount, pa.name 
    FROM Transaction t 
    JOIN p_providerA pa ON pa.aid = t.ref 
WHERE t.prv = 1 

UNION ALL 

SELECT t.*, pb.amount, pb.name 
    FROM Transaction t 
    JOIN p_providerB pb ON pb.bid = t.ref 
WHERE t.prv = 2 

UNION ALL 

    ... 

Die andere Option ist fast ebenso hässlich

SELECT t.* 
    , CASE t.prv 
     WHEN 1 THEN pa.amount 
     WHEN 2 THEN pb.amount 
     WHEN 3 THEN pc.amount 
     END AS `p_amount` 
    , CASE t.prv 
     WHEN 1 THEN pa.name 
     WHEN 2 THEN pb.name 
     WHEN 3 THEN pc.name 
     END AS `p_name` 
    FROM Transaction t 
    LEFT JOIN p_providerA pa ON pa.aid = t.ref AND t.prv = 1 
    LEFT JOIN p_providerB pb ON pb.bid = t.ref AND t.prv = 2 
    LEFT JOIN p_providerC pc ON pc.cid = t.ref AND t.prv = 3 

Unterm Strich ... es gibt keinen Weg beitreten implementieren dynamisch die Providers Tabelle in einer einzigen Abfrage verwenden. Wir könnten diese Informationen in einer Pre-Query verwenden, um eine Ergebnismenge zurückzubekommen, die uns hilft, die Anweisung zu erstellen, die wir ausführen müssen.


Eine weitere Option (wenn die p_providerX Tabellen nicht zu groß ist) wäre all jene zusammen in einer Inline-Ansicht verketten, und das zu, dass beizutreten. (Dies ist für große Mengen teuer sein könnte, die abgeleitete Tabelle könnte einen Index für sie erstellt bekommen ...)

SELECT t.* 
     , p.amount AS p_amount 
     , p.name AS p_name 
    FROM `Transaction` t 
    JOIN (
      SELECT 1 AS pID, pa.aid AS rID, pa.amount, pa.name FROM p_providerA 
      UNION ALL 
      SELECT 2  , pb.bid  , pb.amount, pb.name FROM p_providerB 
      UNION ALL 
      SELECT 3  , pc.cid  , pc.amount, pc.name FROM p_providerC 
      UNION ALL 
      ... 
     ) p 
    ON p.pID = t.pID 
    AND p.rID = t.ref 

Wenn wir immer wieder Anfragen wie das Laufen gehen werden, könnten wir, dass die Inline-Ansicht in eine materialisieren Tisch ... ich kann nur raten bei den Datentypen hier ...

CREATE TABLE p_provider 
(pID  BIGINT UNSIGNED NOT NULL 
, rID  BIGINT UNSIGNED NOT NULL 
, amount DECIMAL(20,2) 
, name  VARCHAR(255) 
, PRIMARY KEY (pID,id) 
); 

INSERT INTO p_provider (pID, rID, amount, name) 
SELECT 1 AS pID, pa.aid AS rID, pa.amount, pa.name FROM p_providerA 
; 
INSERT INTO p_provider (pID, rID, amount, name) 
SELECT 2 AS pID, pb.aid AS rID, pb.amount, pb.name FROM p_providerB 
; 
INSERT INTO p_provider (pID, rID, amount, name) 
SELECT 3 AS pID, pc.aid AS rID, pc.amount, pc.name FROM p_providerC 
; 
... 

Und verweisen dann die neue Tabelle

SELECT ... 
FROM `Transaction` t 
JOIN `p_provider` p 
    ON p.piD = t.pID 
    AND p.rID = t.ref 

natürlich, die neue p_provider Tabelle geht zu nicht synchron sein, wenn Änderungen an p_providerA, p_providerB, et al. vorgenommen werden.

+0

Ich werde den ersten Weg machen, um den Tag zu retten, aber nächsten Schritt werde ich die Struktur ändern. Vielen Dank. – siniradam

Verwandte Themen