2009-07-07 2 views
2

Я довольно свежий для обработки базы данных, но теперь полностью без опыта. Однако я столкнулся с проблемой. Мне нужно сформулировать SQL-запрос, который возвращает все статьи, которые соответствуют , к набору других статей (произвольного размера). Запрос должен быть сгенерирован сценарием в приложении для поиска статей, в которых пользователь может вводить список статей, в которых любые найденные статьи могут использоваться (совместимы) с.Article compatibilty в базе данных SQL

Таким образом, для списка чисел статьи A, B, ..., N, вопрос:
"Дайте мне все статьи, которые совместимы с и B и ... и N"

Вопрос касается только одной таблицы;
Совместимость
artOne
artTwo

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

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

Для примера рассмотрим таблицу
СОВМЕСТИМЫ

 
A B 
---- 
1 2 
3 1 
3 4 

Если бы я хотел, чтобы все статьи, которые совместимы с [1], то запрос будет возвращать [2, 3].
Запрос, сгенерированный списком [2, 3], вернет [1].
Пока запрос, сгенерированный из списка [1, 3], генерирует пустой список.

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

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

Большое спасибо

Marco

+1

Определить структуру таблицы и какой результат вы хотите объяснить подробно – KuldipMCA

+0

Хорошо, спасибо. OP отредактирован. – Nubsis

ответ

1
SELECT id 
FROM (
     SELECT B AS id 
     FROM compat 
     WHERE A IN (list) 
     UNION 
     SELECT A 
     FROM compat 
     WHERE B IN (list) 
     ) q 
GROUP BY 
     id 
HAVING COUNT(*) = @cnt 

, где @cnt - общее количество элементов в вашем списке.

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

Лучше иметь два ограничения: один гарантируя, что пара уникальна, другой проверки, что изделие с наименьшим id быть первым:

ALTER TABLE compat ADD CONSTRAINT ux_compat_ab UNIQUE (A, B) 
ALTER TABLE compat ADD CONSTRAINT cc_compat_order CHECK (A < B) 

Если вы сделаете это, вы можете заменить UNION с более эффективным UNION ALL:

SELECT id 
FROM (
     SELECT B AS id 
     FROM compat 
     WHERE A IN (list) 
     UNION ALL 
     SELECT A 
     FROM compat 
     WHERE B IN (list) 
     ) q 
GROUP BY 
     id 
HAVING COUNT(*) = @cnt 
+0

Это решило! Благодаря тонну! ---- Marco – Nubsis

0

выберите * из статьи внутреннее соединение compatTbl каратов на a.Id = ct.ArticleAID где ct.ArticleBID в (список идентификаторов идти здесь)

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