Wie mache ich eine basierend auf Tabellennamen in SQL beitreten?

stimmen
0

Ok, so haben wir eine Reihe von Tabellen, die wie folgt benannt sind:

training_data_001
training_data_002
training_data_003
training_data_004
training_data_005

Und dann in einer anderen Tabelle auf einem Feld die, die wir schauen zu finden, lassen Sie es uns einfach nennen master.training_type.

Wie auch immer, ich habe mich gefragt, ob jemand eine Möglichkeit, kannte einen seltsamen Tabellennamen mit dieser Art von Daten verbinden basierte zu tun. Etwas wie das:

SELECT foo FROM master WHERE id = ? 
INNER JOIN training_data_${master.training_type}
ON foo.id = training_data_${master.training_type}.foo_id

Ich weiß, dass ich dies auf der Client-Seite tun kann, aber es wäre schön, die db tun zu haben.

Beachten Sie auch: es ist SQL Server.

Update : Ich beschloss, nur um es zu tun auf der Client - Seite. Danke trotzdem alle.

Vielen Dank!

-fREW

Veröffentlicht am 09/12/2008 um 20:54
quelle vom benutzer
In anderen Sprachen...                            


5 antworten

stimmen
2

Sie können nur dynamischen SQL master.training_type lesen verwenden, um eine Zeichenfolge zu erstellen, die Sie dann execute EXEC (@stringvar)

Beantwortet am 09/12/2008 um 20:57
quelle vom benutzer

stimmen
1

Sie können es mit dynamischem SQL in einer gespeicherten proc nur tun. Sie können auch Ansichten oder gespeicherte Prozeduren im Voraus mit Code-Generierung generieren, wenn Sie es im laufenden Betrieb aus Sicherheitsgründen oder aus anderen Gründen nicht tun wollen.

Beantwortet am 09/12/2008 um 20:57
quelle vom benutzer

stimmen
1

Wenn die Tabellen alle die gleiche Struktur, eine erstellen partitionierte Sicht über die Tische und gegen die Ansicht beizutreten. Sie benötigen einen Check - Constraint auf eine Säule (vielleicht ein Date) zu machen , so dass die Abfrage optimiser Partition Elimination tun kann.

Beantwortet am 09/12/2008 um 21:03
quelle vom benutzer

stimmen
1

etwas tun, wie folgt aus:

create view training_data_all as
select '001' as training_type, * from training_data_001
union all
select '002' as training_type, * from training_data_002
union all
select '003' as training_type, * from training_data_003
union all
select '004' as training_type, * from training_data_004
union all
select '005' as training_type, * from training_data_005

dann nur zu / von ihr wählen und kommen:

SELECT foo FROM master WHERE id = ? 
INNER JOIN training_data_all
ON foo.id = training_data_all.foo_id
WHERE training_data_all.training_type = ${master.training_type}

Wenn der Tabellenliste ist an der Zeit zu wachsen / schrumpfen über, können Sie diese gleiche Ansicht dynamisch auf den Tischen basierend schreiben, indem einige Lookups in die Systemtabellen vorhanden ist.

Nichts davon ist jedoch sehr effizient. Kann nur ETL Sie diese Daten in eine kombinierte Tabelle in einem festen Intervall?

Beantwortet am 09/12/2008 um 21:22
quelle vom benutzer

stimmen
1

Die partitionierten Sicht ist ein möglicher Ansatz. Da Sie nur die Auswahl der foo Spalte sind, überprüft man wirklich nur die Existenz einer Zeile in der Trainingstabelle über die INNER JOIN? Außerdem sieht es aus wie Sie versuchen, foo als Alias ​​verwenden in Ihrem beitreten, aber es ist nicht so in der SELECT-Klausel einrichten. Als Ergebnis erraten ich hier auf, was Sie wirklich wollen.

Eine andere Frage ... ist der Satz von Trainingstabellen statisch? Erwarten Sie eine neue Tabelle mit einem neuen Suffixnummer hinzufügen zu können und haben es gerade arbeiten?

Eine andere mögliche Lösung:

SELECT
     foo
FROM
     dbo.master m
WHERE
     (training_type = '001' AND EXISTS (SELECT * FROM dbo.training_data_001 WHERE foo_id = m.id)) OR
     (training_type = '002' AND EXISTS (SELECT * FROM dbo.training_data_002 WHERE foo_id = m.id)) OR
     (training_type = '003' AND EXISTS (SELECT * FROM dbo.training_data_003 WHERE foo_id = m.id)) OR
     (training_type = '004' AND EXISTS (SELECT * FROM dbo.training_data_004 WHERE foo_id = m.id)) OR
     (training_type = '005' AND EXISTS (SELECT * FROM dbo.training_data_005 WHERE foo_id = m.id))

Wenn Sie tatsächlich Spalt zurück aus den Trainingsdatentabellen wollen, dann könnten Sie so etwas wie verwenden:

SELECT
     m.id,
     COALESCE(t1.my_col, t2.my_col, t3.my_col, t4.my_col, t5.my_col) AS my_col
FROM
     dbo.master m
LEFT OUTER JOIN dbo.training_data_001 t1 ON m.training_type = '001' AND t1.foo_id = m.id
LEFT OUTER JOIN dbo.training_data_002 t1 ON m.training_type = '002' AND t2.foo_id = m.id
LEFT OUTER JOIN dbo.training_data_003 t1 ON m.training_type = '003' AND t3.foo_id = m.id
LEFT OUTER JOIN dbo.training_data_004 t1 ON m.training_type = '004' AND t4.foo_id = m.id
LEFT OUTER JOIN dbo.training_data_005 t1 ON m.training_type = '005' AND t5.foo_id = m.id
Beantwortet am 09/12/2008 um 21:43
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more