MySQL - Auswahl von Daten aus mehreren Tabellen, alle mit derselben Struktur, aber unterschiedlichen Daten

79

Ok, hier ist mein Dilemma. Ich habe eine Datenbank mit ungefähr 5 Tabellen eingerichtet, die alle genau dieselbe Datenstruktur haben. Die Daten werden auf diese Weise zu Lokalisierungszwecken und zur Aufteilung von insgesamt rund 4,5 Millionen Datensätzen getrennt.

Meistens wird nur ein Tisch benötigt und alles ist gut. Manchmal werden jedoch Daten aus 2 oder mehr Tabellen benötigt und nach einer benutzerdefinierten Spalte sortiert. Hier habe ich Probleme.

Datenspalten:

id, band_name, song_name, album_name, genre

MySQL-Anweisung:

SELECT * from us_music, de_music where `genre` = 'punk'

MySQL spuckt diesen Fehler aus:

#1052 - Column 'genre' in where clause is ambiguous

Offensichtlich mache ich das falsch. Möchte jemand etwas Licht in diese Sache bringen?

Jayrox
quelle

Antworten:

177

Ich denke, Sie suchen nach der UNION- Klausel, a la

(SELECT * from us_music where `genre` = 'punk')
UNION
(SELECT * from de_music where `genre` = 'punk')
Mihai Limbășan
quelle
@ mihai-limban - tut mir leid, Sie zu stören, aber gibt es eine Möglichkeit, anhand der Ergebnismenge zu erkennen, dass "welches Ergebnis aus welcher Tabelle stammt". Denn wenn wir einen Datensatz aus dieser Ergebnismenge aktualisieren / löschen müssen, gibt es keine Möglichkeit, dies zu wissen.
Web-Nomade
7
@Pushpesh fügt jedem eine eindeutige Zeichenfolgen-ID hinzu SELECT, z. B.:(SELECT 'us_music' AS from_table, * FROM us_music WHERE genre = 'punk') UNION ...
jkrcma
Was ist der Wert des Genres ist unbekannt, aber IDs sollten in zwei Tabellen übereinstimmen? Kannst du so etwas machen? (SELECT 1) AS select1 UNION (SELECT 2) AS select2 WHERE select1.id=select2.id
ZurabWeb
Perfekt, genau warum ich Stack liebe! Google, Stapelfrage und Antwort finden Sie bereits hier! Vielen Dank!
Rocco The Taco
Wie lautet die Syntax, nach der in der UNION der Ergebnismenge gruppiert und dann auch sortiert werden soll? Nehmen wir an, es ist viewCountund movieTitlewo es eine Datenbank für jeden Monat gibt. Sie vereinen alle 12 Tabellen, was in Ordnung ist, aber dann erhalten Sie 12 einzelne Ergebnismengen in der Ausgabe. Was wäre, wenn Sie nur eine Ergebnismenge wollten, in der alle Ergebnisse gruppiert movieTitleund der viewCountWert für jede movieTitleZeile summiert wurden ?
anon58192932
19

Es hört sich so an, als wären Sie mit einem einzigen Tisch glücklicher. Die fünf haben das gleiche Schema und müssen manchmal so dargestellt werden, als ob sie von einem Tabellenpunkt stammen, um alles in einer Tabelle zusammenzufassen.

Fügen Sie eine neue Spalte hinzu, mit der zwischen den fünf Sprachen unterschieden werden kann (ich gehe davon aus, dass sich die Sprache in den Tabellen unterscheidet, da Sie angegeben haben, dass es sich um eine Lokalisierung handelt). Mach dir keine Sorgen über 4,5 Millionen Datensätze. Jede echte Datenbank kann mit dieser Größe problemlos umgehen. Wenn Sie die richtigen Indizes hinzufügen, können Sie sie problemlos als einzelne Tabelle behandeln.

Ned Batchelder
quelle
Ich hatte ursprünglich alle meine Daten in einer einzigen Tabelle, aber nach ungefähr 3,5 Millionen Datensätzen begann es fast 5-10 Sekunden lang zu kriechen. Ich fand es am besten für mich zu teilen, weil es viel schneller war. Ich habe jetzt einen neuen Webhost, also ist es vielleicht besser, aber es scheint zu
mühsam
26
Klingt so, als müssten Sie den Tabellen Indizes hinzufügen.
Ned Batchelder
1
Ja, Sie haben im Wesentlichen ein Symptom eines Problems behandelt, ohne das Kernproblem zu lösen (falsche / unzureichende Indizierung). Was passiert als nächstes, wenn eine Ihrer 5 Tabellen 4,5 Millionen Zeilen erreicht und erneut mit dem Crawlen beginnt?
Lo-Tan
5

Jede der oben genannten Antworten ist gültig, oder eine alternative Möglichkeit besteht darin, den Tabellennamen auch um den Datenbanknamen zu erweitern - z.

SELECT * from us_music, de_music where `us_music.genre` = 'punk' AND `de_music.genre` = 'punk'
Muhen
quelle
Das gibt Ihnen eine sehr schlecht definierte Ergebnismenge: alle möglichen Paare von us_ und de_ Punk.
David Schmitt
4

Die Spalte ist mehrdeutig, da sie in beiden Tabellen angezeigt wird. Sie müssten das Feld where (oder sort) vollständig angeben, z. B. us_music.genre oder de_music.genre. Normalerweise würden Sie jedoch zwei Tabellen angeben, wenn Sie sie dann zusammenfügen würden etwas Mode. Die Struktur, mit der Sie sich befassen, wird gelegentlich als partitionierte Tabelle bezeichnet, obwohl dies normalerweise dazu dient, das Dataset auch in verschiedene Dateien zu unterteilen, anstatt das Dataset nur willkürlich aufzuteilen. Wenn Sie für die Datenbankstruktur verantwortlich sind und es keinen guten Grund gibt, die Daten zu partitionieren, würde ich eine große Tabelle mit einem zusätzlichen "Ursprungs" -Feld erstellen, das einen Ländercode enthält, aber Sie tun dies wahrscheinlich aus legitimen Leistungsgründen . Verwenden Sie entweder eine Union, um die Tabellen zu verknüpfen , an denen Sie interessiert sind : http: //dev.mysql.oder mithilfe der Merge-Datenbank-Engine http://dev.mysql.com/doc/refman/5.1/en/merge-storage-engine.html .


quelle
3

Ihr ursprünglicher Versuch, beide Tabellen zu überspannen, erzeugt einen impliziten JOIN. Dies wird von den meisten erfahrenen SQL-Programmierern missbilligt, da es die zu kombinierenden Tabellen mit der Bedingung wie trennt.

Dies UNIONist eine gute Lösung für die Tabellen, aber es sollte keinen Grund geben, warum sie nicht mit einer anständigen Indizierung in eine Tabelle eingefügt werden können. Ich habe gesehen, dass das Hinzufügen des richtigen Index zu einer großen Tabelle die Abfragegeschwindigkeit um drei Größenordnungen erhöht.

staticsan
quelle
3

Die unionAussage verursacht eine Deal-Zeit in riesigen Datenmengen. Es ist gut, die Auswahl in 2 Schritten durchzuführen:

  1. Wählen Sie die ID
  2. Wählen Sie dann die Haupttabelle damit aus
mehdi mohamadi
quelle