2014-12-15 4 views
1

Я пытаюсь разрешить пользователям показывать количество совпадающих строк в базе данных progs, используя до 4 различных параметров.Поиск шести полей несколько раз

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

Я ищу для genre_id на любой из строк - genre_id1, genre_id2, genre_id3, genre_id4, genre_id5 или genre_id6.

Так, чтобы найти число правильных совпадений для одного жанра ид, я использую этот код:

$total=0; 
for ($i = 1; $i < 7; $i++) { 
$howmany = mysql_result(mysql_query("SELECT COUNT(*) as Num FROM `progs` WHERE `genre_id$i` 
='$genre_id'"),0); 
$total=$total+$howmany; } 

Приведенный выше код работает, чтобы показать, как много матчей за один genre_id. Но тогда я хочу искать еще 3-х жанровых идентификатора. Поэтому я хочу показать случаи, когда все 4 представленных идентификатора жанра появляются либо на genre_id1, genre_id2, genre_id3, genre_id4, genre_id5 или genre_id6.

Я хочу получить ряд результатов и показать результирующие строки.

Я не могу понять, как я могу это сделать. Любая помощь оценивается.

Happy Christmas!

Ник

ответ

1

Нормализация базы данных

Вещь, которую Вы должны спросить себя, почему вы структурированы базы данных, то, как вы сделали.

Было бы гораздо разумнее иметь только один жанр в каждой строке. Таким образом, вы можете просто подсчитать количество строк, которые соответствуют определенному идентификатору. Почему у вас есть 6 genre_ids в ваших рядах?

Если вам нужно 6 на 'прог', то просто создайте новую таблицу, названную «жанрами» и привяжите ее к таблице «progs». Как это:

CREATE TABLE `progs` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    <any other fields> 
) 

CREATE TABLE `genres` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `prog_id` int(11) 
    <any other fields> 
) 

Здесь prog_id ссылается на progs таблице. Теперь эта вторая, гораздо более простая таблица намного проще делать запросы. Теперь также возможно иметь только 3 жанра на «прогу» или 9. Это намного более гибко, чем только 6 похожих полей в одной строке.

См: http://databases.about.com/od/specificproducts/a/normalization.htm

+0

Спасибо за ваш комментарий. Я думаю, вы можете быть правы. Я унаследовал базу данных, и я думаю, что ваше предложение - лучшее решение. – Mrchuckles

0

У вас есть пара вариантов

Используйте "обратный" IN:

WHERE $genre_id IN (genre_id1, genre_id2, .... genre_id6) 

или записать их в полном объеме:

WHERE genre_id1 = $genre_id OR genre_id2 = $genre_id OR .... $genre_id = genre_id6 

Если вы вам понадобится счет PER-FIELD, тогда вам понадобится что-то вроде:

SELECT SUM(genre_id1 = $genre_id) AS id1_matches, 
    SUM(genre_id2 = $genre_id) AS id2_matches 
    etc... 

где MySQL будет принимать логическое значение истина/ложь из id = $id тестов, конвертировать, что в целое 0 и 1, а затем суммировать 1 «с.

+0

Я не знал об обратном в подходе. Очень полезно знать. Спасибо – Mrchuckles

0

Одним из вариантов было бы написать запрос, который использует оператор IN и убедитесь, что genre_id в списке вы хотите, как это:

SELECT SUM(
    (CASE WHEN genre_id1 IN (four_genre_ids) THEN 1 ELSE 0 END) + 
    (CASE WHEN genre_id2 IN (four_genre_ids) THEN 1 ELSE 0 END) + 
    (CASE WHEN genre_id3 IN (four_genre_ids) THEN 1 ELSE 0 END) + 
    (CASE WHEN genre_id4 IN (four_genre_ids) THEN 1 ELSE 0 END) + 
    (CASE WHEN genre_id5 IN (four_genre_ids) THEN 1 ELSE 0 END) + 
    (CASE WHEN genre_id6 IN (four_genre_ids) THEN 1 ELSE 0 END)) AS totalMatches 
FROM myTable; 

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

+1

Спасибо за ваш комментарий. Я думаю, что лучшим решением является уборка моей базы данных, но этот подход IN - это то, что я мог бы использовать в будущем. Полезно знать, спасибо. – Mrchuckles