выгрузка данных из нескольких таблиц с общими полями - PullRequest
2 голосов
/ 12 апреля 2011

Привет всем. У меня есть несколько таблиц, в которых есть некоторые общие поля, связывающие их вместе, но я не могу придумать, как правильно их дампить.

Как правило, пользователям будет предоставлено два теста, и каждый тест может быть пройден несколько раз.

В основной таблице хранится информация о пользователе и тесте, аналогичная приведенной ниже (мы назовем эту таблицу MAIN):

user_id     test     iteration    completion_time
   1         1          1              1:00
   1         2          1              1:30
   1         1          2              0:49
   1         2          2              1:30

Каждая тестовая страница имеет свою собственную таблицу для хранения предоставленных ответов, поскольку на некоторых страницах есть тонна вопросов. Мы назовем эту примерную таблицу РЕЗУЛЬТАТЫ, но есть много подобных таблиц, которые в основном одинаковы.

user_id     test     iteration     q1   q2   q3
   1         1          1          A    B    A
   1         2          1          B    B    A
   1         1          2          A    B    B
   1         2          2          A    B    B

Эти таблицы результатов (опять же, их много) в основном хранят результаты, а также достаточно информации, чтобы точно связать результаты во всех таблицах. Я настроил это так, потому что использование только одной таблицы для результатов оставило бы меня с таблицей из нескольких сотен столбцов, которые я прочитал, не рекомендуется.

Так что проблема в том, что я не могу понять, как лучше связать эти таблицы и получить результаты. Я прочитал об объединениях и союзах, и, насколько я могу судить, ни один из них не кажется правильным, потому что мне нужно извлекать данные из ~ 10-15 таблиц одновременно.

Я могу сделать огромный сложный выбор - что-то вроде

select m.*, a.*, b.*, c.* from main m, results_a a, results_b b, results_c c where a.user_id=m.user_id and b.user_id=m.user_id and c.user_id=m.user_id'

и это работает, но должен быть лучший способ. Имейте в виду, что в этом примере я дал только 3 таблицы результатов - в моем реальном приложении это будет больше похоже на 15-20 таблиц результатов.

Помимо того, что он действительно сложный, он возвращает дубликаты некоторых строк и, если я хочу добавить какую-либо дополнительную логику (скажем, например, что мне нужны только те же данные, которые я запрашивал ранее, но только для теста 2), он становится еще сложнее. И давайте даже не будем говорить о сортировке.

Из того, что я прочитал, JOIN предназначен для 2 таблиц, а UNION объединяет строки результатов, а не столбцы.

Я не претендую на звание эксперта mysql, но я изучил это перед публикацией. Я чувствую, что должен быть близок к правильному ответу, но просто не совсем прихожу к нему.

Может кто-нибудь дать мне какое-нибудь руководство?

Ответы [ 2 ]

1 голос
/ 12 апреля 2011

Чтобы использовать внутренние объединения, попробуйте:

SELECT m.*, a.*, b.*, c.* 
FROM main m
INNER JOIN results_a a ON a.user_id = m.user_id
INNER JOIN results_b b ON b.user_id = m.user_id
INNER JOIN results_c c ON c.user_id = m.user_id
WHERE m.user_id = x

Чтобы различать имена столбцов, явно укажите имя столбца и присвойте псевдоним

SELECT m.*, a.q1 as A_Q1, a.q2 as A_Q2, b.q1 as B_Q1, b.q2 as B_Q2 ...
0 голосов
/ 12 апреля 2011

Я думаю, что вы создали свою базу данных таким образом, что вам придется выполнять объединения. Звучит лучше, чем альтернатива (большой, ненормированный стол). Что вы пытаетесь выбраться? Просмотреть все тесты и определить лучший результат пользователя?

Так что, если я понимаю таблицы, у вас есть несколько пользователей (очевидно). Каждый пользователь может пройти несколько тестов. Каждый тест можно пройти несколько раз.

select m.*, a.*, b.*, c.* from main m 
join results_a a
on a.user_id = m.user_id and a.test_id = m.test_id and a.iteration_id = m.iteration_id
join results_b b
on b.user_id = m.user_id and b.test_id = m.test_id and b.iteration_id = m.iteration_id
join results_c c
on c.user_id = m.user_id and c.test_id = m.test_id and c.iteration_id = m.iteration_id

Это должно дать вам одну строку на итерацию, на тест, на пользователя. Если вы хотите определенный тест для пользователя, то добавьте:

where m.user_id = @userid and m.test_id = @testid

и затем вы можете просмотреть все итерации для теста пользователем.

Если вы хотите последнюю итерацию: select top(1) ...

where m.user_id = @userid and m.test_id = @testid 
order by m.iteration_id desc

Вы можете подумать о создании представления, когда ваши вопросы настроены, поэтому вам не нужно генерировать оператор select во время выполнения, представляющий конкретный тест.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...