Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Поиск по словам
 
 автор: nikolayers   (23.07.2013 в 05:37)   письмо автору
 
 

Есть таблица, в виде: | ID | Слово |
ID - идентификатор человека, слово - любое варчар слово.
Суть - каждый юзер сайта описывает свой характер 1 словом, таких описаний у каждого юзера много. Тоесть в таблице может быть много записей с разными словами, прочее...

Цель - другой пользователь ищет текущего путем вписывания 6 ключевых слов. Нужно чтобы достался из бд юзер, у которого максимальное число совпадений с этими поисковыми словами.
Предпологаю, что нужно использовать GROUP BY по ID, но как ранжировать по максимальному количеству совпадений???
Группируя, мы получим множество слов которое принадлежит конкретному человеку - но как быть дальше...

  Ответить  
 
 автор: nikolayers   (23.07.2013 в 05:43)   письмо автору
 
   для: nikolayers   (23.07.2013 в 05:37)
 

Рабочий пример:
В бд записи
id | word
-----------
1 | Злой
1 | Сердитый
1 | Наглый

2 | Агрессивный
2 | Злой

-----------------
В поиске пишется ЗЛОЙ СЕРДИТЫЙ Белый зеленый красный .... и должно вернуть через селект юзера с id1 так как там макс. число совпадений

  Ответить  
 
 автор: Sfinks   (23.07.2013 в 08:55)   письмо автору
 
   для: nikolayers   (23.07.2013 в 05:43)
 

SELECT id
FROM tbl
WHERE word IN('ЗЛОЙ','СЕРДИТЫЙ','Белый','зеленый','красный')
GROUP BY id
ORDER BY count(*) DESC
LIMIT 1

  Ответить  
 
 автор: nikolayers   (23.07.2013 в 14:59)   письмо автору
 
   для: Sfinks   (23.07.2013 в 08:55)
 

Спасибо огромное, работает))

  Ответить  
 
 автор: nikolayers   (23.07.2013 в 18:46)   письмо автору
 
   для: Sfinks   (23.07.2013 в 08:55)
 

Помогите пожалуйста еще...я модифицировал код под свои нужды:
$pat - массив из 6-ти слов
$s - количество введенных слов в поиске
$c - сколько должно минимально совпасть поисковых слов с табличными

Это сделано для того, чтобы пользователи, которые вводят 1 слово, никак не могли достать из базы характеристику например из 6ти слов


SELECT `user` FROM `words`
    WHERE `user` IN (SELECT `user` 
        FROM `words`
        WHERE `word` IN ('{$pat[0]}', '{$pat[1]}','{$pat[2]}','{$pat[3]}','{$pat[4]}','{$pat[5]}')
        AND `user`!='".$user."'
        GROUP BY `user`
        HAVING count(*) >= ".$c."
        ORDER BY count(*) DESC 
        )
    GROUP BY `user`
    HAVING count(*) <= ".++$s."
    LIMIT 1


Сам код работает, я проверил много вариантов (не исключаю ошибок)...Но мне кажется, что моя реализация - не единственно правильная и совсем не изящная...Возможно ли код сократить или переделать более правильно?

  Ответить  
 
 автор: Sfinks   (23.07.2013 в 19:17)   письмо автору
 
   для: nikolayers   (23.07.2013 в 18:46)
 

А вот так разве не тоже самое получится?
SELECT `user`  
FROM `words` 
WHERE `word` IN ('{$pat[0]}', '{$pat[1]}','{$pat[2]}','{$pat[3]}','{$pat[4]}','{$pat[5]}') 
  AND `user`!='".$user."' 
GROUP BY `user` 
HAVING count(*) >= ".$c."
  AND count(*) <= ".++$s."
ORDER BY count(*) DESC  
LIMIT 1

А почему ++$s, а не просто $s?

Ну и аккуратнее будет так выглядеть:
SELECT `user`, count(*)co
FROM `words` 
WHERE `word` IN ('{$pat[0]}', '{$pat[1]}','{$pat[2]}','{$pat[3]}','{$pat[4]}','{$pat[5]}') 
  AND `user`!='".$user."' 
GROUP BY `user` 
HAVING co BETWEEN ".$c." AND ".++$s."
ORDER BY co DESC  
LIMIT 1

  Ответить  
 
 автор: nikolayers   (23.07.2013 в 19:49)   письмо автору
 
   для: Sfinks   (23.07.2013 в 19:17)
 

помоему разница есть)) в моем случае внутренний селект считает COUNT(*) по совпавшим, а внешний считает ОБЩЕЕ количество всех слов пользователя...возможно ошибаюсь)) но скрипт дает разные результаты для моего и вашего примера

  Ответить  
 
 автор: Sfinks   (23.07.2013 в 21:16)   письмо автору
 
   для: nikolayers   (23.07.2013 в 19:49)
 

Возможно.... Хотя странно.

В любом случае
        ORDER BY count(*) DESC  
в подзапросе лишнее и ни на что не влияет.

Хм... не доходит пока до меня почему разные результаты.... Возможно нужно меньше работать =)

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования