SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 20.07.2009 17:14:23

XPOMOB
Участник
Зарегистрирован: 20.07.2009
Сообщений: 11

Релевантный поиск по параметрам (ака помогите написать запрос)

Есть база, примерно такая:
CREATE TABLE `test` (
`text` TEXT NOT NULL ,
`param1` TINYINT NOT NULL ,
`param2` TINYINT NOT NULL ,
`param3` TINYINT NOT NULL ,
`param4` TINYINT NOT NULL
);

параметров (paramх) может быть и больше...

Если написать

SELECT *
FROM `test`
WHERE `param1` =1
AND `param2` =1
AND `param3` =1
AND `param4` =1
LIMIT 0 , 30


то ничего не находится (или находится только 1 результат), а если написать

SELECT *
FROM `test`
WHERE `param1` =1
or `param2` =1
or `param3` =1
or `param4` =1
LIMIT 0 , 30


то выбираются большое количество строк (или вообще все выбирается).

Можно ли сделать такой выбор, что бы выбралось большое количество строк, но отсортированный они были по релевантности. например, если выбраем строку с параметрами 1 1 1 1, то на первое место ставилась строка с 0 1 1 1, а не 1 0 0 0 (т.к. в первом варианте совпадений больше, чем во втором).


//вместо 1 и 0 планируется использовать цифры (не только 1 и 0)

Неактивен

 

#2 20.07.2009 18:39:55

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

http://sqlinfo.ru/forum/viewtopic.php?pid=4046#p4046

SELECT if(param1+param2+param3+param4=4,1,
if(param1+param2+param3+param4=3,2,
if(param1+param2+param3+param4=2,3,
if(param1+param2+param3+param4=1,4,5)))), at.* FROM at
WHERE `param1` =1
OR `param2` =1
OR `param3` =1
OR `param4` =1
order by 1
LIMIT 0 , 30;

Неактивен

 

#3 20.07.2009 19:16:39

XPOMOB
Участник
Зарегистрирован: 20.07.2009
Сообщений: 11

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

vasya написал:

SELECT if(param1+param....

Этот запрос почему-то не работает sad

SELECT IF (
param1 + param2 + param3 + param4 =4, 1,
IF (
param1 + param2 + param3 + param4 =3, 2,
IF (
param1 + param2 + param3 + param4 =2, 3,
IF (
param1 + param2 + param3 + param4 =1, 4, 5
)
)
)
), test . *
FROM test
WHERE `param1` =0
OR `param2` =1
OR `param3` =1
OR `param4` =1
ORDER BY 1
LIMIT 0 , 30

выдает на первом месте 1 1 1 1
на втором 0 1 1 1
хотя должен выдавать на первом 0 1 1 1

Неактивен

 

#4 20.07.2009 19:24:29

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

Запрос работает как надо. На первом месте он выводит 1111 так как вариантов совпадений больше, чем с 0111 (я понял смысл задачи таким образом и соответствующе определил параметр по которому будет идти сортировка).
Если сумма параметров равна 4 (т.е. 1111), то дополнительное поле, по которому идет сортировка принимается равным 1.

Определите дополнительное поле лубым другим (нужным вам образом).

Неактивен

 

#5 20.07.2009 19:35:33

XPOMOB
Участник
Зарегистрирован: 20.07.2009
Сообщений: 11

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

vasya написал:

Запрос работает как надо...

А как мне его переделать, что бы работал такой запрос? он сейчас не работает

SELECT IF (
param1 + param2 + param3 + param4 =4, 1,
IF (
param1 + param2 + param3 + param4 =3, 2,
IF (
param1 + param2 + param3 + param4 =2, 3,
IF (
param1 + param2 + param3 + param4 =1, 4, 5
)
)
)
), test . *
FROM test
WHERE `param1` =4
OR `param2` =4
OR `param3` =5
OR `param4` =5
ORDER BY 2
LIMIT 0 , 30


Получается, что на первом месте 5 5 5 5, а не 4 4 5 5 (т.е. сортировки никакой не происходит)


ORDER BY 2 - зачем это? Замена числа никакого влияния не оказывает на результаты и все работает также, если это вообще удалить.

Неактивен

 

#6 20.07.2009 19:50:12

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

В части ORDER BY можно использовать алиас или номер позиции колонки в перечислении выводимых колонок после SELECT
Например,
SELECT id FROM t ORDER BY 1 DESC;
тоже самое, что и
SELECT id FROM t ORDER BY id DESC;

В моем примере ORDER BY 1 означает, что сортирока происходит по первому полю, формирующемуся конструкцией вложенных if.

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

Неактивен

 

#7 20.07.2009 20:05:49

XPOMOB
Участник
Зарегистрирован: 20.07.2009
Сообщений: 11

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

vasya написал:

В части ORDER BY можно использовать алиас или номер позиции колонки в перечислении выводимых колонок после SELECT

Про ORDER BY все понял.


но в моем случае сортировать результаты по 1 колонке видимо не получится. Можно ли отсортировать результаты по количеству совпадений?

Неактивен

 

#8 20.07.2009 20:10:20

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

XPOMOB написал:

но в моем случае сортировать результаты по 1 колонке видимо не получится.

Почему?

XPOMOB написал:

Можно ли отсортировать результаты по количеству совпадений?

А первая колонка для чего предназначена?

Неактивен

 

#9 20.07.2009 20:36:25

XPOMOB
Участник
Зарегистрирован: 20.07.2009
Сообщений: 11

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

vasya написал:

XPOMOB написал:

но в моем случае сортировать результаты по 1 колонке видимо не получится.

Почему?

XPOMOB написал:

Можно ли отсортировать результаты по количеству совпадений?

А первая колонка для чего предназначена?

XPOMOB написал:

но в моем случае сортировать результаты по 1 колонке видимо не получится.

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

В первой колонке хранится нужная нам информация (текст или ещё каике данные), а во всех остальных (param_хх) данные для сравнения. Использовать буду так: нужно найти в базе что отвечающее определенным параметрам, но строки с определенными параметрами там может не оказатся (поэтом условие and ставить нельзя) (а если и окажется - нужно же посмотреть похожие строки, с примерно такими же параметрами). Т.к. точного сопадения там не будет - мне хотелось бы увидеть хотябы похожие результаты, в которых 1 или 2 параметра отличаются.


Например нужно найти транзистор в базе отвечающий определенным параметрам: 1 ватт и 10 вольт в SMD-корпусе. Такого транзистора в базе нет. Хотелось бы увидет хотя бы все, у которых 1 ватт и 10 вольт (1вариант), а также 1 ватт и корпус соответствующий (2вариант), и 10 вольтовые в нужном корпусе (3вариант).

Пока писал - возник вопрос - кого первым ставить: 1 вариант, второ или третий варианты. Тут бы конечно хорошо какой-нибудь коэффициент полезности внести... но не знаю пока... (это не обязательно). Можно просто отсортировать результаты по одному, наиболее важному параметру (по мощности - например).

Неактивен

 

#10 20.07.2009 20:54:05

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

XPOMOB написал:

В первой колонке хранится нужная нам информация (текст или ещё каике данные),

Первая колонка это конструкция if. В приведенном мной примере первая колонка как раз и содержит информацию о кол-ве совпадений.

Возможно в вашем случае будет удобней составить запрос через union http://sqlinfo.ru/forum/viewtopic.php?id=1597

Неактивен

 

#11 20.07.2009 20:57:54

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

XPOMOB написал:

Можно просто отсортировать результаты по одному, наиболее важному параметру (по мощности - например).

В этом случае вообще никаких вопросов не возникает.

SELECT * FROM `test`
WHERE `param1` =1
OR `param2` =1
OR `param3` =1
OR `param4` =1
ORDER BY paramx
LIMIT 0 , 30

Где paramx - наиболее важный параметр (например, мощность).

Неактивен

 

#12 20.07.2009 21:11:03

XPOMOB
Участник
Зарегистрирован: 20.07.2009
Сообщений: 11

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

vasya написал:

XPOMOB написал:

Можно просто отсортировать результаты по одному, наиболее важному параметру (по мощности - например).

В этом случае вообще никаких вопросов не возникает.

SELECT * FROM `test`
WHERE `param1` =1
OR `param2` =1
OR `param3` =1
OR `param4` =1
ORDER BY paramx
LIMIT 0 , 30

Где paramx - наиболее важный параметр (например, мощность).

простая сортировка по 1 параметру не дает нужного результата.
Пример:
база заполнена вот такми значениями:
5 5 5 5
4 5 5 5
4 4 5 5
4 4 4 5


мы делаем запрос SELECT * FROM `test`
WHERE `param1` =4
OR `param2` =5
OR `param3` =5
OR `param4` =5
ORDER BY param4
LIMIT 0 , 30

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

Неактивен

 

#13 20.07.2009 21:25:42

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

Понятно, не правильно понял предыдущее сообщение.

Раз вам нужна сортировка в зависимости от кол-ва совпадений, то считайте эти совпадения и сортируйте по ним.
Вам было предложено два варианта как это сделать:
1) дополнительное поле с конструкцией if
2) пользовательская переменная и запрос через union

Неактивен

 

#14 20.07.2009 21:39:35

XPOMOB
Участник
Зарегистрирован: 20.07.2009
Сообщений: 11

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

vasya написал:

Вам было предложено два варианта как это сделать:
1) дополнительное поле с конструкцией if

предложенный вариант с if у меня не работает

SELECT IF (
param1 + param2 + param3 + param4 =4, 1,
IF (
param1 + param2 + param3 + param4 =3, 2,
IF (
param1 + param2 + param3 + param4 =2, 3,
IF (
param1 + param2 + param3 + param4 =1, 4, 5
)
)
)
), test. *
FROM test
WHERE `param1` =4
OR `param2` =4
OR `param3` =4
OR `param4` =5
ORDER BY 1
LIMIT 0 , 30

база заполнена

база заполнена вот такми значениями:
5 5 5 5
4 5 5 5
4 4 5 5
4 4 4 5

на выходе получаем
база заполнена вот такми значениями:
5 5 5 5
4 5 5 5
4 4 5 5
4 4 4 5
хотя должны получить в точности до наоборот.

И если не очень сложно, можете пояснить, что значит + и цифры 2, 3? Почему не - и 6, 10?
param1 + param2 + param3 + param4 =2, 3,

Неактивен

 

#15 20.07.2009 21:51:19

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

XPOMOB написал:

И если не очень сложно, можете пояснить, что значит + и цифры 2, 3? Почему не - и 6, 10?
param1 + param2 + param3 + param4 =2, 3,

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

param1 + param2 + param3 + param4 означает сумму четырех параметров.
Приведенная в примере конструкция означает, что если сумма четырех параметров равна 4, то значение поля принимается равным 1, в противном случае
если сумма четырех параметров равна 3, то значение поля принимается равным 2, в противном случае и т.д.

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

Неактивен

 

#16 20.07.2009 22:22:12

XPOMOB
Участник
Зарегистрирован: 20.07.2009
Сообщений: 11

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

vasya написал:

param1 + param2 + param3 + param4 означает сумму четырех параметров...

Теперь понятно, нужно было сразу с этого начить smile

Только вот проблема получается, если у меня 10 параметров, то мне нужно создать 10^10 вариантов (if-ов). PHP с этим наверное справится, но размерчик запроса получится огромным... и долго наверное такой запрос обрабатывать...


А можно сделать вот так?

if (param1 = искомому_числу) {
если равно - значит к какой-то временной переменной прибавить 1, а если не равно - ничего не делать
и потом отсортировать по этой переменной
}

это условие повторить для каждого параметра.

Вопрос: как сделать эту переменную?

Неактивен

 

#17 20.07.2009 22:32:14

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

XPOMOB написал:

Только вот проблема получается, если у меня 10 параметров, то мне нужно создать 10^10 вариантов (if-ов). PHP с этим наверное справится, но размерчик запроса получится огромным... и долго наверное такой запрос обрабатывать...

У вас будет 10 if-ов. Совпадают 10 параметров, совпадают 9 параметров, ..., совпадает 1 параметр.

XPOMOB написал:

Вопрос: как сделать эту переменную?

Пользовательские переменные http://sqlinfo.ru/forum/viewtopic.php?id=363
ранее в этой теме была уже ссылка http://sqlinfo.ru/forum/viewtopic.php?id=1597

Неактивен

 

#18 20.07.2009 22:55:18

XPOMOB
Участник
Зарегистрирован: 20.07.2009
Сообщений: 11

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

vasya написал:

Пользовательские переменные

По ссылкам прочитал - ничего не понял, набрал в гугл - там вроде бы по понятнее. Короче вот что у меня примерно получилось, но пишет, что ошибка в третьей строке.





SELECT @rr =0
IF (
param1 =4@rr = @rr +1
)
IF (
param2 =4 @rr + +
)
IF (
param3 =4 @rr + +
)
IF (
param4 =5 @rr + +
), test. *
FROM test
WHERE `param1` =4
OR `param2` =4
OR `param3` =4
OR `param4` =5
ORDER BY @rr DESC
LIMIT 0 , 30

 


как отделить 4 от @? ставил запятую, не помогло.
param1 =4@rr = @rr +1


можно ли использовать
@rr++
@rr++7

Неактивен

 

#19 20.07.2009 23:13:32

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

1. Вы читали http://sqlinfo.ru/forum/viewtopic.php?pid=4046#p4046 ?
if() имеет три параметра.


2. SELECT @rr =0  неправильная запись.
http://sqlinfo.ru/forum/viewtopic.php?id=363
Пользовательские переменные (user variable).
Пользовательские переменные записываются как @var_name, действуют в течении сессии, не чувствительны к регистру.
Могут быть определены следующими способами:
2) В выражениях select с помощью оператора ' := '

Сравните

(none) >select @rr = 0;
+---------+
| @rr = 0 |
+---------+
|    NULL |
+---------+
1 row in set (0.00 sec)

(none) >select @rr := 0;
+----------+
| @rr := 0 |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)



3.

XPOMOB написал:

можно ли использовать
@rr++
@rr++7

(none) >select @rr:=0;
+--------+
| @rr:=0 |
+--------+
|      0 |
+--------+
1 row in set (0.00 sec)

(none) >select @rr++;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds
 to your MySQL server version for the right syntax to use near '' at line 1

(none) >select @rr++7;
+--------+
| @rr++7 |
+--------+
|      7 |
+--------+
1 row in set (0.00 sec)

(none) >select @rr;
+------+
| @rr  |
+------+
|    0 |
+------+
1 row in set (0.00 sec)

 

Неактивен

 

#20 20.07.2009 23:29:35

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

XPOMOB написал:


SELECT @rr =0
IF (
param1 =4@rr = @rr +1
)
IF (
param2 =4 @rr + +
)
IF (
param3 =4 @rr + +
)
IF (
param4 =5 @rr + +
), test. *
FROM test
WHERE `param1` =4
OR `param2` =4
OR `param3` =4
OR `param4` =5
ORDER BY @rr DESC
LIMIT 0 , 30
 

Ваш запрос не имеет смысла. В результате выполнения у вас будет первая колонка if(...) и переменная @rr, имеющаяя какое-то значение. Какую сортировку по вашему будет осуществлять запись ORDER BY @rr DESC ?

Неактивен

 

#21 20.07.2009 23:38:57

XPOMOB
Участник
Зарегистрирован: 20.07.2009
Сообщений: 11

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

vasya написал:

Ваш запрос не имеет смысла.

Так как же все же посчитать количество совпадений?

Неактивен

 

#22 21.07.2009 00:12:54

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

Сделать дополнительную колонку с помощью вложенных if-ов, в которой считать количество совпадений. Совпало 10 параметров, присваете значение 10, совпало 9 параметров, присваиваете значение 9 и т.д. Сортировать по этому полю.

Пользовательские переменные в этом случае вам не нужны.

select if(param1=$p1,1,0)+if(param2=$p2,1,0)+...+if(paramN=$pN,1,0), `test`.*
from `test` where param1 = $p1 or param2 = $p2 or ... paramN = $pN
order by 1 desc limit 0,30;

Неактивен

 

#23 21.07.2009 13:03:20

XPOMOB
Участник
Зарегистрирован: 20.07.2009
Сообщений: 11

Re: Релевантный поиск по параметрам (ака помогите написать запрос)

vasya написал:

select if(param1=$p1,1,0)+if(param2=$p2,1,0)+...+if(paramN=$pN,1,0), `test`.*
from `test` where param1 = $p1 or param2 = $p2 or ... paramN = $pN
order by 1 desc limit 0,30;

Урааа!!! Работает. smile smile Спасибо.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson