2010-09-14 3 views
3

У меня есть таблица категорий с:самостоятельной ссылочной таблицы и рекурсивная функция SQL

  • CategoryId
  • parentCategoryID
  • CategoryName

и таблицу продуктов с:

  • itemID
  • CategoryId
  • ITEMNAME

Я использую MySQL. Я хочу написать запрос, который будет возвращать количество элементов в категории с учетом идентификатора категории. Запрос должен возвращать общий счет для всех элементов во всех подкатегориях данной категории.

Надеюсь, это имеет смысл. Извините, если я не использую правильную номенклатуру.

+0

Есть ли количество подкатегорий в каждой категории, возможно? – Fanis

+0

Возможный дубликат [Рекурсивный запрос MySQL?] (Http://stackoverflow.com/questions/3704130/recursive-mysql-query) –

+0

максимум 2 уровня .. поэтому основные родительские категории имеют подкатегории .. но эти категории в настоящее время не имеют подкатегорий. – rodrick

ответ

2

Как вы застряли на этой схеме? Это называется «Adjacency List», и это достаточно просто, концептуально, но у него есть некоторые реальные недостатки. Самым значительным из которых является невозможность запроса для всех потомков.

Взгляните на это, и рассмотреть вопрос о целесообразности альтернативного метода, представляющих деревья могли бы работать лучше для вас:

http://pugs.postgresql.org/files/ModelingTrees.pdf

+0

Ссылка не действительна. –

0

конечно его можно, но не очень эффективно. вы должны идти с вложенными набор структур: http://intelligent-enterprise.informationweek.com/001020/celko1_1.jhtml;jsessionid=AFUXE0ZF4PTNXQE1GHPSKH4ATMY32JVN

если вы не любите, что есть посмотреть здесь: взглянуть на это: http://explainextended.com/2010/04/18/hierarchical-query-in-mysql-limiting-parents/

0

если, как вы говорите, есть только два уровня категорий, простой запрос join/alias будет работать нормально. Если вы допускаете произвольные глубины, вам придется пойти с фантастическими рекурсивными запросами или наборами смещений и еще чего-то.

Предполагая, что вы только позволяют элементы, которые будут присоединены к «нижней» категории, то что-то вроде вы должны получить необходимые результаты:

SELECT top.categoryID, top.categoryName, bottom.categoryID, bottom.categoryName, 
    COUNT (items.itemID) 
FROM categories AS top 
LEFT JOIN categories AS bottom ON top.categoryID = bottom.parentCategoryID 
LEFT JOIN items ON bottom.categoryID = items.categoryID 
WHERE (bottom.categoryID = $your_category) 
GROUP BY top.categoryID, bottom.categoryID 

Если вам нужно смотреть на только категории верхнего уровня, то при необходимости измените предложение WHERE.

+1

нормально, я думаю, что это будет работать отлично .. но я ошибался, есть три уровня .. может ли этот запрос быть изменен, чтобы обрабатывать три возможных уровня? – rodrick

0

Если вы рассматриваете альтернативные подходы, описанные в document ссылается Jeff Dege, к текущей структуре списка смежности дерева:

Nested Sets очень быстро для данных, которые часто читают, но изменения редко (читает использование SQL BETWEEN и индексы, изменения могут быть дорогими, поскольку они могут обновлять многие существующие записи), в то время как Перечисление пути (также известный как Материализованный путь) обеспечивает приемлемую хорошую производительность при использовании индексов и LIKE '[path]%' запросов (по крайней мере, для MySQL как насколько я знаю) и хорошую производительность для операций вставки и приемлемую производительность при перемещении категории в другую категорию.

У меня лично есть проект, в котором я использую опцию Путь с идентификаторами базы данных в качестве элементов пути и точкой . для разделения элементов (например, путь предка 1.2.3.).

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

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