Выберите продукты, где категория принадлежит любой категории в иерархии

У меня была проблема несколько раз. Во всех этих ситуациях настройки BIOS были в порядке. Выполнение файла .bat не помогло, пока я не запустил его как администратор и не перезагрузил компьютер. Пару раз мне приходилось делать это пару раз, прежде чем он начал работать.

Так что попробуйте

  1. Откройте меню «Пуск» и найдите «Командная строка»
  2. Щелкните правой кнопкой мыши и выберите «Запуск от имени администратора»
  3. Перейдите к «C: \ TwinCAT \ 3.1 \ Система "записав" cd C: \ TwinCAT \ 3.1 \ System "
  4. Выполните .bat, написав" win8settick.bat "
  5. Перезагрузка - повторите, если не работает [114 ]

Для меня это всегда решало проблему. Если у вас неправильные настройки BIOS, вы получите другую ошибку, в которой говорится о виртуализации (насколько я знаю).

8
задан Cade Roux 13 October 2008 в 13:23
поделиться

9 ответов

Лучшее решение для этого на этапе проектирования баз данных. Ваша таблица категорий должна быть Вложенным Набором. Статья Managing Hierarchical Data в MySQL не то, что конкретный MySQL (несмотря на заголовок), и дает замечательный обзор различных методов хранения иерархии в таблице базы данных.

Резюме:

Вложенные наборы

  • Выборы легки для любой глубины
  • Вставляет и удаляет, тверды

Стандарт parent_id базирующаяся иерархия

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

Таким образом на основе Вашего примера, если бы Ваша таблица иерархии была вложенным набором, Ваш запрос выглядел бы примерно так:

SELECT * FROM products 
   INNER JOIN categories ON categories.id = products.category_id 
WHERE categories.lft > 2 and categories.rgt < 11

2 и 11 являются левым и правым соответственно Processors запись.

6
ответ дан 5 December 2019 в 19:04
поделиться

Похож на задание для Общего Выражения Таблицы.. что-то вроде:

with catCTE (catid, parentid)
as
(
select cat.catid, cat.catparentid from cat where cat.name = 'Processors'
UNION ALL
select cat.catid, cat.catparentid from cat inner join catCTE on cat.catparentid=catcte.catid
)
select distinct * from catCTE

Это должно выбрать категорию, именем которой являются 'Процессоры' и любой из, его - потомки, должен смочь использовать это в В пункте для задержки продуктов.

3
ответ дан 5 December 2019 в 19:04
поделиться

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

categoriesSet = empty set
while new.size > 0:
  new = select * from categories where parent in categoriesSet
  categoriesSet = categoriesSet+new

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

0
ответ дан 5 December 2019 в 19:04
поделиться

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

  • Если уровень вложения категорий известен, или можно найти верхнюю границу: Создайте ужасно выглядящий ВЫБОР с помощью большого количества СОЕДИНЕНИЙ. Это быстро, но ужасно, и необходимо установить предел на уровнях иерархии.
  • Если Вы имеете относительно небольшое количество общих категорий, запрашиваете их всех (просто идентификаторы, родители), собираете идентификаторы тех, Вы заботитесь об и делаете ВЫБОР.... В Для продуктов. Это было подходящим вариантом для меня.
  • Запросите/вниз иерархию с помощью серии ВЫБОРОВ. Простой, но относительно медленный.
  • Я полагаю, что последние версии SQLServer имеют некоторую поддержку рекурсивных запросов, но не использовали их сам.

Хранимые процедуры могут помочь, если Вы не хотите делать эту сторону приложения.

0
ответ дан 5 December 2019 в 19:04
поделиться
CREATE TABLE #categories (id INT NOT NULL, parentId INT, [name] NVARCHAR(100))
INSERT INTO #categories
    SELECT 1, NULL, 'Computers'
    UNION
SELECT 2, 1, 'Processors'
    UNION
SELECT 3, 2, 'Intel'
    UNION
SELECT 4, 2, 'AMD'
    UNION
SELECT 5, 3, 'Pentium'
    UNION
SELECT 6, 3, 'Core 2 Duo'
    UNION
SELECT 7, 4, 'Athlon'
SELECT * 
    FROM #categories
DECLARE @id INT
    SET @id = 2
            ; WITH r(id, parentid, [name]) AS (
    SELECT id, parentid, [name] 
        FROM #categories c 
        WHERE id = @id
        UNION ALL
    SELECT c.id, c.parentid, c.[name] 
        FROM #categories c  JOIN r ON c.parentid=r.id
    )
SELECT * 
    FROM products 
    WHERE p.productd IN
(SELECT id 
    FROM r)
DROP TABLE #categories   

Последняя часть примера на самом деле не работает при выполнении его прямо как это. Просто удалите выбор из продуктов и замены с простым ВЫБОРОМ * ОТ r

0
ответ дан 5 December 2019 в 19:04
поделиться

Возможно, что-то как:

select *
from products
where products.category_id IN
  (select c2.category_id 
   from categories c1 inner join categories c2 on c1.category_id = c2.parent_id
   where c1.category = 'Processors'
   group by c2.category_id)

[РЕДАКТИРОВАНИЕ], Если бы глубина категории больше, чем одна, что это сформировало бы Ваш самый внутренний запрос. Я подозреваю, что Вы могли разработать хранимую процедуру, которая выполнит развертку в таблице, пока идентификаторы, возвращенные внутренним запросом, не имели детей - вероятно, лучше, чтобы иметь атрибут, который отмечает категорию как нижний характеристический класс в иерархии - затем выполняют внешний запрос на тех идентификаторах.

0
ответ дан 5 December 2019 в 19:04
поделиться

Это должно рекурсивно вызвать вниз все 'дочерние' категории, начинающие с данной категории.

DECLARE @startingCatagoryId int
DECLARE @current int
SET @startingCatagoryId = 13813 -- or whatever the CatagoryId is for 'Processors'

CREATE TABLE #CatagoriesToFindChildrenFor
(CatagoryId int)

CREATE TABLE #CatagoryTree
(CatagoryId int)

INSERT INTO #CatagoriesToFindChildrenFor VALUES (@startingCatagoryId)

WHILE (SELECT count(*) FROM #CatagoriesToFindChildrenFor) > 0
BEGIN
    SET @current = (SELECT TOP 1 * FROM #CatagoriesToFindChildrenFor)

    INSERT INTO #CatagoriesToFindChildrenFor
    SELECT ID FROM Catagory WHERE ParentCatagoryId = @current AND Deleted = 0

    INSERT INTO #CatagoryTree VALUES (@current)
    DELETE #CatagoriesToFindChildrenFor WHERE CatagoryId = @current
END

SELECT * FROM #CatagoryTree ORDER BY CatagoryId

DROP TABLE #CatagoriesToFindChildrenFor
DROP TABLE #CatagoryTree
0
ответ дан 5 December 2019 в 19:04
поделиться

мне нравится использовать таблицу временного файла стека для hierarchal данных. вот грубый пример -

-- create a categories table and fill it with 10 rows (with random parentIds)
CREATE TABLE Categories ( Id uniqueidentifier, ParentId uniqueidentifier )
GO

INSERT
INTO   Categories
SELECT NEWID(),
       NULL 
GO

INSERT
INTO   Categories
SELECT   TOP(1)NEWID(),
         Id
FROM     Categories
ORDER BY Id
GO 9


DECLARE  @lvl INT,            -- holds onto the level as we move throught the hierarchy
         @Id Uniqueidentifier -- the id of the current item in the stack

SET @lvl = 1

CREATE TABLE #stack (item UNIQUEIDENTIFIER, [lvl] INT)
-- we fill fill this table with the ids we want
CREATE TABLE #tmpCategories (Id UNIQUEIDENTIFIER)

-- for this example we’ll just select all the ids 
-- if we want all the children of a specific parent we would include it’s id in
-- this where clause
INSERT INTO #stack SELECT Id, @lvl FROM Categories WHERE ParentId IS NULL

WHILE @lvl > 0
BEGIN -- begin 1

      IF EXISTS ( SELECT * FROM #stack WHERE lvl = @lvl )
      BEGIN -- begin 2

      SELECT @Id = [item]
      FROM #stack
      WHERE lvl = @lvl

      INSERT INTO #tmpCategories
      SELECT @Id

      DELETE FROM #stack
      WHERE lvl = @lvl
      AND item = @Id

      INSERT INTO #stack
      SELECT Id, @lvl + 1
      FROM   Categories
      WHERE  ParentId = @Id

      IF @@ROWCOUNT > 0
      BEGIN -- begin 3
         SELECT @lvl = @lvl + 1
      END -- end 3
   END -- end 2
   ELSE
   SELECT @lvl = @lvl - 1

END -- end 1

DROP TABLE #stack

SELECT * FROM #tmpCategories
DROP TABLE #tmpCategories
DROP TABLE Categories

существует хорошее объяснение здесь текст ссылки

0
ответ дан 5 December 2019 в 19:04
поделиться

Мой ответ на другой вопрос от пары несколько дней назад применяет здесь... рекурсию в SQL

Существуют некоторые методы в книге, которую я связал, который должен покрыть Вашу ситуацию приятно.

0
ответ дан 5 December 2019 в 19:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: