SQLite объединяет значения похожих записей в одну

В моей базе данных SQLite у меня есть таблица Tracks, которая состоит из следующих столбцов: исполнитель, трек, жанр1, жанр2, жанр3. Таблица содержит много значений, которые имеют одинаковые значения исполнителя и трека с разными значениями жанра1, жанр2, жанр3. Как в примере ниже:

artist | track   | genre1  | genre2 | genre3
ABBA   | Song 1  | Rock    | Rock   |  Rock
U2     | Song 4  | Rock    | Rock   |  Rock
ABBA   | Song 1  | Pop     | Pop    |  Pop
U2     | Song 4  | Pop     | Pop    |  Pop
ABBA   | Song 1  | 70s     | 70s    |  70s
U2     | Song 4  | 90s     | 90s    |  90s

Мне нужно создать оператор SQLite, который объединит все уникальные значения жанра, где исполнитель и трек совпадают, как в примере, показанном ниже:

artist | track   | genre1  | genre2 | genre3
ABBA   | Song 1  | Rock    | Pop    |  70s
U2     | Song 4  | Pop     | Rock   |  90s

Любая помощь в этом будет очень признательна.


person Adam    schedule 18.06.2015    source источник
comment
Ужасный дизайн БД. Действительно, вам следует узнать о нормализации.   -  person Phantômaxx    schedule 19.06.2015


Ответы (1)


К сожалению, похоже, вы страдаете от плохого дизайна базы данных. В приведенном выше дизайне вы ограничены только 3 жанрами для каждой песни, и когда к песне применим только один жанр, вы просто повторяете одно и то же значение во всех полях жанра. В хорошем дизайне вы должны иметь возможность иметь как можно больше или меньше записей о жанрах для каждой песни, а также вы также можете уменьшить объем данных, необходимых для хранения значений жанра.

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

Итак, как же нам этого добиться... Сначала давайте создадим таблицу под названием «Жанры». У меня должно быть два поля: целочисленный первичный ключ и строка для значения жанра с уникальным ограничением на последнее. Далее нам понадобится таблица сопоставления (для дальнейшего использования давайте назовем ее SongGenre), таблица, которая имеет только два поля внешнего ключа, одно для ссылки на таблицу песен и одно для ссылки на таблицу жанров. В каждой записи будет указано, что этот жанр принадлежит этой песне, и у нас может быть несколько записей для каждой песни.

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

SELECT Artist, Track, Group_Concat(Genre.GenreName) 
FROM Song 
JOIN SongGenre USING (SongID) 
JOIN Genre USING (GenreID) 
GROUP BY Artist, Track;
person BenCamps    schedule 18.06.2015