Взвешивание запросов MySql - PullRequest
2 голосов
/ 21 июля 2011

Я осмотрелся и нашел несколько вопросов, подобных моему, но у них нет объяснения.

Я пытаюсь найти таблицу с несколькими столбцами. Я хочу, чтобы строки с наибольшим количеством совпадающих столбцов находились вверху, а строки с наименьшим - снизу. Я видел несколько способов сделать. Мой нынешний и ужасный способ - это выполнение множества MySQL-запросов и PHP.

Пример

    +----+-----------+----------+------+-------+
    | ID | firstName | lastName | more | stuff |
    +----+-----------+----------+------+-------+
    |  1 | Bob       | Hope     |    1 |   450 |
    |  2 | Steve     | Hope     |    0 |    29 |
    |  3 | Gary      | Flops    |    1 |     8 |
    +----+-----------+----------+------+-------+

Я хочу иметь возможность искать lastName = Hope OR more = 1 Я хотел бы, чтобы Боб Хоуп был на вершине, потому что он соответствует двум запрошенным вещам. Я знаю, что в этом примере это то, что произойдет, но это только пример.

Если я сделаю запрос; lastName = Hope OR firstName = Steve. Стив должен быть наверху, а затем Боб

Надеюсь, это легко понять. Кто-нибудь может дать мне подробный пример с объяснением.

Ответы [ 3 ]

5 голосов
/ 22 июля 2011

Как насчет этого:

SELECT
  id,
  firstName,
  lastName,
  more,
  stuff,
  (lastName = 'Hope') + (firstName = 'Steve') AS weight
FROM mytable
ORDER BY weight DESC;

Результат:

+----+-----------+----------+------+-------+--------+
| id | firstName | lastName | more | stuff | weight |
+----+-----------+----------+------+-------+--------+
|  2 | Steve     | Hope     |    0 |    29 |      2 |
|  1 | Bob       | Hope     |    1 |   450 |      1 |
|  3 | Gary      | Flops    |    1 |     8 |      0 |
+----+-----------+----------+------+-------+--------+
1 голос
/ 22 июля 2011

Помимо отличного ответа Майка, есть еще один вариант:

SELECT
    id,
    firstName,
    lastName,
    more,
    stuff,
    COUNT(m1.id) + COUNT(m2.id)
      AS weight
FROM
    mytable AS m

      LEFT JOIN
    mytable AS m1
        ON  m1.id = m.id
        AND m1.lastName = 'Hope'

      LEFT JOIN
    mytable AS m2
        ON  m2.id = m.id
        AND m2.firstName = 'Steve'  

GROUP BY m.id
HAVING COUNT(m1.id) + COUNT(m2.id) > 0    
ORDER BY weight DESC;

и еще один:

SELECT
    m.id,
    m.firstName,
    m.lastName,
    m.more,
    m.stuff,
    COUNT(*) AS weight
FROM
    mytable AS m
      JOIN
        ( SELECT id
          FROM mytable
          WHERE lastName = 'Hope'
        UNION ALL
          SELECT id
          FROM mytable
          WHERE firstName = 'Steve'  
        ) AS c
        ON c.id = m.id
GROUP BY m.id  
ORDER BY weight DESC;
1 голос
/ 21 июля 2011

Самым простым способом, который я могу придумать, является MATCH() ... AGAINST. Вы можете сортировать по «счету».

SELECT ID, firstName, LastName, stuff, more, MATCH(firstName,LastName,more,stuff) AGAINST ('words to search for'  IN BOOLEAN MODE) AS score
FROM yourTable 
WHERE MATCH(firstName,LastName,more,stuff) AGAINST ('words to search for'  IN BOOLEAN MODE)
ORDER BY score

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

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