Как правильно сделать SQL UPDATE с взвешенным подвыбором? - PullRequest
3 голосов
/ 24 апреля 2010

Я, вероятно, пытаюсь сделать слишком много за один запрос, но у меня есть база данных sqlite с плохо отформатированными рецептами. Это возвращает отсортированный список рецептов с добавленной релевантностью:

SELECT *, sum(relevance) FROM (
  SELECT *,1 AS relevance FROM recipes WHERE ingredients LIKE '%milk%' UNION ALL
  SELECT *,1 AS relevance FROM recipes WHERE ingredients LIKE '%flour%' UNION ALL
  SELECT *,1 AS relevance FROM recipes WHERE ingredients LIKE '%sugar%'
) results GROUP BY recipeID ORDER BY sum(relevance) DESC;

Но теперь я застрял в особом случае, когда мне нужно записать значение релевантности в поле в той же строке, что и рецепт. Я понял что-то вроде этого:

UPDATE recipes SET relevance=(SELECT sum(relevance) ...)

Но я пока не смог заставить это работать. Я буду продолжать пытаться, но пока, пожалуйста, дайте мне знать, как бы вы подошли к этому?

Редактировать: Оценивая решение Питера, я столкнулся с некоторыми серьезными проблемами с производительностью, из-за объема данных, над которыми нужно было выполнить операции. Я написал небольшой скрипт Rebol, который выполняет циклы, поиск и фиксацию в пакетах по 1000 строк. Это завершилось за пару минут.

1 Ответ

2 голосов
/ 24 апреля 2010

Вы действительно должны исправить свою модель (см. Ниже).

Если вы не можете, следующий запрос должен работать (я пробовал, и он работал, как я ожидал).

Update recipes
Set relevance =
(
  Select   Case When ingredients Like '%milk%' Then 1 Else 0 End
         + Case When ingredients Like '%flour%' Then 1 Else 0 End
         + ...
  From recipes r2
  Where r2.recipe_id = recipes.recipe_id
)

Используется Case для суммирования всех подходящих ингредиентов.


Предлагаемая модель:

  • Таблица recipes

  • Таблица ingredients

  • Таблица recipe_ingredients

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