MySQL: selección de datos de varias tablas, todas con la misma estructura pero con datos diferentes

79

Ok, aquí está mi dilema. Tengo una base de datos configurada con aproximadamente 5 tablas, todas con la misma estructura de datos exacta. Los datos se separan de esta manera con fines de localización y para dividir un total de aproximadamente 4,5 millones de registros.

La mayoría de las veces solo se necesita una mesa y todo está bien. Sin embargo, a veces se necesitan datos de 2 o más de las tablas y es necesario ordenarlos por una columna definida por el usuario. Aquí es donde estoy teniendo problemas.

columnas de datos:

id, band_name, song_name, album_name, genre

Declaración de MySQL:

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

MySQL escupe este error:

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

Obviamente, estoy haciendo esto mal. ¿Alguien quiere arrojarme algo de luz sobre esto?

Jayrox
fuente

Respuestas:

177

Creo que estás buscando la cláusula UNION , a la

(SELECT * from us_music where `genre` = 'punk')
UNION
(SELECT * from de_music where `genre` = 'punk')
Mihai Limbășan
fuente
@ mihai-limban: lamento molestarlo, pero ¿hay alguna manera de reconocer en el conjunto de resultados que "qué resultado vino de qué tabla"? Porque, si necesitamos actualizar / eliminar un registro de este conjunto de resultados, no hay forma de saberlo.
web-nomad
7
@Pushpesh agrega un identificador de cadena único a cada SELECT, por ejemplo:(SELECT 'us_music' AS from_table, * FROM us_music WHERE genre = 'punk') UNION ...
jkrcma
¿Cuál es el valor del género que se desconoce, pero los identificadores deben coincidir en dos tablas? ¿Puedes hacer algo como esto? (SELECT 1) AS select1 UNION (SELECT 2) AS select2 WHERE select1.id=select2.id
ZurabWeb
Perfecto, ¡exactamente por qué me encanta Stack! ¡Google, encuentre la pila de preguntas y respuestas ya aquí! ¡Gracias!
Rocco The Taco
¿Cuál es la sintaxis para agrupar en la UNIÓN del conjunto de resultados y luego también realizar el orden? Digamos que es viewCounty movieTitledonde hay una base de datos para cada mes. Une las 12 tablas juntas, lo cual está bien, pero luego obtiene 12 conjuntos de resultados individuales en la salida. ¿Qué pasa si solo desea un conjunto de resultados donde todos los resultados se agrupan movieTitley el viewCountvalor se suma para cada movieTitlefila?
anon58192932
19

Parece que te gustaría tener una sola mesa. Los cinco tienen el mismo esquema y, a veces, deben presentarse como si vinieran de un punto de tabla para ponerlo todo en una sola tabla.

Agregue una nueva columna que se pueda usar para distinguir entre los cinco idiomas (supongo que es un idioma que es diferente entre las tablas, ya que dijo que era para la localización). No se preocupe por tener 4,5 millones de registros. Cualquier base de datos real puede manejar ese tamaño sin problemas. Agregue los índices correctos y no tendrá problemas para tratarlos como una sola tabla.

Ned Batchelder
fuente
Originalmente tenía todos mis datos en una sola tabla, pero casi comenzó a arrastrarse durante 5-10 segundos después de alrededor de 3,5 millones de registros. Descubrí que dividirlo funcionaba mejor para mí porque era mucho más rápido. Ahora tengo un nuevo servidor web, por lo que puede ser mejor, pero parece demasiado complicado combinarlo
Jayrox
26
Parece que necesita agregar índices a las tablas.
Ned Batchelder
1
Sí, básicamente trató un síntoma de un problema sin resolver el problema principal (indexación inadecuada / insuficiente). ¿Qué pasará a continuación si una de sus 5 tablas alcanza los 4,5 millones de filas y comienza a rastrear de nuevo?
Lo-Tan
5

Cualquiera de las respuestas anteriores es válida, o una forma alternativa es expandir el nombre de la tabla para incluir también el nombre de la base de datos, por ejemplo:

SELECT * from us_music, de_music where `us_music.genre` = 'punk' AND `de_music.genre` = 'punk'
Mugir
fuente
lo que le da un conjunto de resultados muy mal definido: todos los pares posibles de us_ y de_ punk.
David Schmitt
4

La columna es ambigua porque aparece en ambas tablas, necesitaría especificar el campo dónde (u ordenar) completamente, como us_music.genre o de_music.genre, pero generalmente especificaría dos tablas si luego las uniera en algo de moda. La estructura con la que está tratando se conoce ocasionalmente como una tabla particionada, aunque generalmente también se hace para separar el conjunto de datos en archivos distintos en lugar de dividir el conjunto de datos arbitrariamente. Si está a cargo de la estructura de la base de datos y no hay una buena razón para dividir los datos, entonces crearía una tabla grande con un campo de "origen" adicional que contiene un código de país, pero probablemente lo esté haciendo por razones legítimas de rendimiento. . Utilice una unión para unir las tablas en las que está interesado http: //dev.mysql.o utilizando el motor de base de datos Merge http://dev.mysql.com/doc/refman/5.1/en/merge-storage-engine.html .


fuente
3

Su intento original de abarcar ambas tablas crea un JOIN implícito. Los programadores SQL más experimentados desaprueban esto porque separa las tablas que se deben combinar con la condición del cómo.

El UNIONes una buena solución para las tablas, ya que son, pero no debería haber ninguna razón por la que no se pueden poner en la mesa con la indexación decente. He visto que agregar el índice correcto a una tabla grande aumenta la velocidad de consulta en tres órdenes de magnitud.

estático
fuente
3

La uniondeclaración provoca un tiempo de negociación en datos enormes. Es bueno realizar la selección en 2 pasos:

  1. seleccione la identificación
  2. luego seleccione la tabla principal con ella
mehdi mohamadi
fuente