2016-08-23 2 views
2

У меня есть 3 таблицы:Mysql соответствия утяжеленных тегов

  • статья (идентификатор, название, ...)
  • article_tag (article_id, tag_id)
  • тега (идентификатор, сортировки, ...)

Я нашел связанную статью (в статью с идентификатором 400 в примере) путем сортировки по числу совпадающих тегов с:

SELECT at1.article_id, COUNT(at1.tag_id) AS tag_count 
FROM article_tag AS at1 
INNER JOIN article_tag AS at2 ON at1.tag_id = at2.tag_id 
WHERE at2.article_id = 400 
GROUP BY at1.article_id 
HAVING at1.article_id != 400 
ORDER BY COUNT(at1.tag_id) DESC 
LIMIT 0 , 20 

Это прекрасно работает. Теперь я не хочу добавлять вес к разным типам тегов. В теге таблицы есть поле с именем sort. Это int, указав тип тега. У меня не было разного значения. Я могу поместить эти множители в другую таблицу или поместить их непосредственно в SQL-код (всего 6 видов). Я бы предпочел последний метод, потому что тогда я могу более легко настроить мультипликаторы. Как я могу это сделать?

+0

Позвольте мне получить это прямо ... вы спрашиваете, следует ли хранить значение, которое может быть изменено как код жесткой кодировки ... или как данные в таблице? если данные могут быть изменены. кем, как часто? и хотя какой пользовательский интерфейс? – xQbert

+0

Жаль, что неясно. Моя проблема заключается в том, как написать новый SQL, чтобы использовать мультипликаторы. Множители могут быть либо жестко закодированы, либо в новой таблице. Но проблема в новом SQL ... – user3336208

+0

Почему бы не добавить столбец в таблицу тегов, называемую sort_weight или что-то еще ... а затем, когда вы присоединитесь к таблице тегов, она будет доступна. Я предполагаю, что tag.sort имеет только один возможный вес. На мой взгляд, я не понимаю требования на этом этапе весов и того, как он используется в отношении тегов сортировки и других данных ... Примеры данных с ожидаемыми результатами могут быть clairify – xQbert

ответ

2

Вы можете использовать CASE выражение

SELECT at1.article_id, 
     SUM(CASE at1.sort 
      WHEN 1 THEN 5 
      WHEN 2 THEN 3 
      ... 
      WHEN 6 THEN 15 
      END) AS tag_weight 
... 
ORDER BY tag_weight DESC 
LIMIT 0, 20 

Или вы можете присоединиться к подзапрос, который генерирует связанные веса.

SELECT at1.aticle_id, SUM(weights.weight) AS tag_weight 
FROM article_tag AS at1 
INNER JOIN article_tag AS at2 ON at1.tag_id = at2.tag_id 
INNER JOIN (
    SELECT 1 AS sort, 3 AS weight 
    UNION 
    SELECT 2, 3 
    UNION 
    ... 
    SELECT 6, 15 
) as weights ON at1.sort = weights.sort 
WHERE at2.article_id = 400 
GROUP BY at1.article_id 
HAVING at1.article_id != 400 
ORDER BY tag_weight DESC 
LIMIT 0 , 20 
+0

Выглядит очень чисто. Существуют ли какие-либо различия в производительности с помощью case и subquery? – user3336208

+0

Не знаю, извините. Оцените это и посмотрите. Вероятно, это зависит от того, создает ли MySQL индекс в производной таблице. – Barmar

Смежные вопросы