MySQL - вибір даних із декількох таблиць, всі з однаковою структурою, але різними даними


79

Гаразд, ось моя дилема: у мене створена база даних із приблизно 5 таблицями, усі з точно такою ж структурою даних. Дані відокремлюються таким чином для цілей локалізації та загального розподілу близько 4,5 мільйонів записів.

Більшість часу потрібен лише один стіл, і все добре. Однак іноді потрібні дані з 2 або більше таблиць, і їх потрібно сортувати за визначеним користувачем стовпцем. Тут я маю проблеми.

стовпці даних:

id, band_name, song_name, album_name, genre

Статистика MySQL:

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

MySQL видає цю помилку:

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

Очевидно, я роблю це неправильно. Хтось хоче пролити це світло для мене?

Відповіді:


177

Я думаю, ви шукаєте пункт UNION , а-ля

(SELECT * from us_music where `genre` = 'punk')
UNION
(SELECT * from de_music where `genre` = 'punk')

@ mihai-limban - вибачте, що заважаю вам, але чи є спосіб розпізнати з набору результатів те, "який результат прийшов з якої таблиці". Оскільки, якщо нам потрібно оновити / видалити запис із цього набору результатів, це неможливо знати.
web-nomad

7
@Pushpesh додає унікальний ідентифікатор рядка до кожного SELECT, наприклад:(SELECT 'us_music' AS from_table, * FROM us_music WHERE genre = 'punk') UNION ...
jkrcma

Яке значення жанру невідомо, але ідентифікатори повинні збігатися в двох таблицях? Ви можете зробити щось подібне? (SELECT 1) AS select1 UNION (SELECT 2) AS select2 WHERE select1.id=select2.id
ZurabWeb

Ідеально, саме тому я люблю Stack! Google, знайдіть запитання та відповідь на стек вже тут! Дякую!
Rocco The Taco

Який синтаксис групувати на UNION набору результатів, а потім також виконувати порядок? Скажімо, це viewCountі movieTitleде є одна БД на кожен місяць. Ви об’єднаєте всі 12 таблиць разом, що нормально, але тоді ви отримаєте 12 окремих наборів результатів у результатах. Що робити , якщо ви просто хотіли один набір результатів , де все результати були згруповані по movieTitleі viewCountзначення було підсумовуються для кожної movieTitleрядки?
anon58192932

19

Здається, ти був би щасливішим за єдиним столом. П'ятеро мають однакову схему, і іноді їх потрібно представляти так, ніби вони прийшли з однієї таблиці, і вказують все це в одній таблиці.

Додайте новий стовпець, за яким можна розрізнити п’ять мов (я припускаю, що мова відрізняється серед таблиць, оскільки ви сказали, що це для локалізації). Не хвилюйтеся про наявність 4,5 мільйона записів. Будь-яка реальна база даних може впоратися з таким розміром без проблем. Додайте правильні індекси, і у вас не буде проблем з ними працювати як з єдиною таблицею.


Спочатку у мене були всі дані в одній таблиці, але вони почали майже повзати протягом 5-10 секунд після приблизно 3,5 мільйонів записів. Я виявив, що розподіл його найкраще для мене працював, оскільки це було набагато швидше. зараз у мене новий веб-хостинг, тож він може бути і кращим, але здається занадто великим
клопотом

26
Здається, вам потрібно додати індекси до таблиць.
Нед Батчелдер, 03

1
Так, ви по суті лікували симптом проблеми, не вирішивши основну проблему (неправильне / недостатнє індексування). Що буде далі, якщо одна з ваших 5 таблиць досягне 4,5 мільйонів рядків і знову почне повзати?
Ло-Тан,

5

Будь-яка з наведених вище відповідей є вірною, або альтернативним способом є розширення імені таблиці, включаючи також ім’я бази даних - наприклад:

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

що дає вам дуже погано визначений набір результатів: усі можливі пари us_ та de_ punk.
Девід Шмітт

4

Стовпець неоднозначний, оскільки він відображається в обох таблицях, і вам потрібно буде вказати поле де (або сортувати) повністю, наприклад us_music.genre або de_music.genre, але зазвичай ви вказуєте дві таблиці, якщо тоді збираєтеся об'єднати їх у якась мода. Структуру, з якою ви маєте справу, іноді називають секціонованою таблицею, хоча це зазвичай роблять, щоб розділити набір даних на окремі файли, а не просто довільно розділити набір даних. Якщо ви відповідаєте за структуру бази даних і немає поважних причин розділяти дані, тоді я створив би одну велику таблицю з додатковим полем "походження", що містить код країни, але ви, мабуть, робите це з законних причин . Або скористайтесь об’єднанням, щоб приєднати таблиці, які вас цікавлять http: //dev.mysql.або за допомогою механізму баз даних Merge http://dev.mysql.com/doc/refman/5.1/en/merge-storage-engine.html .


3

Ваша оригінальна спроба охопити обидві таблиці створює неявний JOIN. Найбільш досвідчені SQL-програмісти на це придивляються, оскільки вони розділяють таблиці, що об’єднуються, із умовою як.

Це UNIONхороше рішення для таблиць, якими вони є, але не повинно бути жодної причини, щоб їх не можна було помістити в одну таблицю з гідною індексацією. Я бачив, як додавання правильного індексу до великої таблиці збільшує швидкість запиту на три порядки.


3

Ця unionзаява спричиняє угоду у величезних даних. Добре виконати вибір у 2 кроки:

  1. виберіть ідентифікатор
  2. потім виберіть основну таблицю з нею
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.