2013-05-10 3 views
1

У меня есть таблица вроде этого:Разница между двумя SELECT,

CREATE TABLE navigation_trees (
    id INT NOT NULL PRIMARY KEY, 
    parent_id INT NULL, 
    template_id NOT NULL 
) 

Потому что внешний ключ при этом parent_id ссылается на идентификатор той же таблицы, при попытке удалить строку, которая ссылается parent_id из другая строка нарушает ссылочную целостность. SQL Server не разрешит ON DELETE CASCADE из-за (очевидного) потенциала для круговых опорных каскадов.

Итак, я пытаюсь удалить все строки с идентификатором шаблона, отличным от (158, 159). Чтобы сделать это, я пытаюсь выбрать все строки, которые НЕ являются объектом ссылки (т. Е. Ни один другой родительский массив другой строки этой строки), удалить их, а затем повторить процесс в цикле, пока их больше нет удалить. Каждый раз, когда пакет удаляется, любой, у которого есть родительский элемент, освобождает ссылочные строки на следующем проходе.

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

метода
-- method one: temp table for filtering template IDs 
SELECT id, parent_id 
INTO #navTrees 
FROM navigation_trees 
WHERE template_id NOT IN (158, 159) 

SELECT DISTINCT tnt1.id 
INTO #set1 
FROM #navTrees AS tnt1 
LEFT OUTER JOIN #navTrees AS tnt2 ON tnt1.id = tnt2.parent_id 
WHERE tnt2.parent_id IS NULL 

-- method two: filtering template IDs directly in the join 
SELECT DISTINCT tnt1.id 
INTO #set2 
FROM navigation_trees AS tnt1 
LEFT OUTER JOIN navigation_trees AS tnt2 ON tnt1.id = tnt2.parent_id 
WHERE tnt2.parent_id IS NULL 
    AND tnt1.template_id NOT IN (158, 159) 

SELECT COUNT(*) 
FROM #set1 
-- Produces: 106023 

SELECT COUNT(*) 
FROM #set2 
-- Produces: 102575 

DROP TABLE #navTrees 
DROP TABLE #set1 
DROP TABLE #set2 

ТЕмпа таблицы, кажется, ловя дополнительные неверные строки, и вот почему он не выполняет проверку ссылочной целостности. Почему они производят различное количество строк?

ответ

2

После разделения непредоставления (158, 159) шаблонов во временную таблицу, используя первый метод, вы не смотрите на (158, 159) шаблонов больше. Но, как показывают цифры, некоторые из шаблонов не должны быть родителями для некоторых из (158, 159) только только. Первый метод не отфильтровывает их, а второй делает.

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

+1

Или по-другому, второй набор правильно рассматривает дочерние элементы из любого 'template_id', а не только дочерние элементы в отфильтрованном наборе. У данных явно есть некоторые родители, которые нельзя удалить даже хотя их 'template_ids' не 158 или 159. – ErikE

+0

Это имеет больше смысла для меня, и сопрягается с тем, что второй набор методов меньше. Спасибо за помощь, ребята! –

1

Разница в том, что в методе 2 набор данных tnt2 все еще имеет в нем шаблоны 158 и 159. поэтому некоторые записи, принадлежащие этим шаблонам, могут быть присоединены к tnt1, давая вам больше записей, чем метод 1. Это не может быть выполнено в методе один, потому что эти шаблоны были удалены из обоих наборов данных (tnt1 и tnt2) до объединения. Попробуйте добавить это к ИНЕК Методы 2 AND tnt2.template_id NOT IN (158, 159)

+0

Это была моя первоначальная мысль, но метод two * не дает больше результатов *, он производит меньше! Когда я добавляю дополнительное условие к предложению WHERE в методе 2, я получаю возвращенные результаты * 0 *; Я не уверен, почему это так :( –

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