2013-04-24 2 views
2

Я провел довольно много времени в Google и в последние несколько дней, но я не могу найти ответ на свою проблему. Не зная точно, как сформулировать проблему в разумный вопрос, это немного сложнее. Вы не знаете, чего не знаете, не так ли?Построение SQL-запроса, который не включает данные на основе иерархии

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

клиентов Таблица - хранит данные клиента

[CustId] | [CustName] 
--------------------- 
1  | John Smith 
2  | Jane Doe 
3  | John Doe 

таблицу кодов - содержит данные кода

[CodeId] | [CodeDesc] 
--------------------- 
A  | A Desc 
B  | B Desc 
C  | C Desc 
D  | D Desc 
E  | E Desc 

CustomerCode Таблица - Объединяет клиентов с кодами

[CustId] | [CodeId] 
------------------- 
1  | A 
1  | B 
2  | B 
2  | C 
2  | D 
3  | C 
3  | E 

CodeHierarchy Таблица - Иерархия кодов, которые не должны быть включены (DropCode), если клиент имеет ConditionCode

[ConditionCode] | [DropCode] 
---------------------------- 
A    | B 
B    | C 
B    | D 

Сейчас я попытаюсь объяснить мой актуальный вопрос.

То, что я пытаюсь выполнить, это написать запрос (представление), в котором будут перечислены коды, основанные на таблице CodeHierarchy.

Результаты были бы что-то вроде этого:

[CustName] | [CodeId] 
------------------- 
John Smith | A 
Jane Doe | B 
John Doe | C 
John Doe | E 

Код B нет в списке для Джона Смита, так как он имеет код A. Коды C и D не перечислены для Джейн Доу, так как она также имеет код B John Doe содержит все коды (обратите внимание, что E даже не находится в таблице CodeHierarchy).

Я пробовал несколько разных вещей (внутренние соединения, объединения слева и справа, подзапросы и т. Д.), Но я просто не могу получить результаты, которые я ищу.

В качестве базового запроса, это возвращает все коды:

SELECT 
    Customer.CustomerName, 
    Code.CodeDesc 
FROM 
    Customer 
     INNER JOIN CustomerCode 
      ON Customer.CodeId = CustomerCode.CodeId 
     INNER JOIN Code 
      ON CustomerCode.CodeId = Code.CodeId 

возвращает только коды, которые ConditionCodes (я понимаю, почему, но я, хотя это может быть стоит выстрел в то время):

SELECT 
    Customer.CustomerName, 
    Code.CodeDesc 
FROM 
    Customer 
     INNER JOIN CustomerCode 
      ON Customer.CodeId = CustomerCode.CodeId 
     INNER JOIN Code 
      ON CustomerCode.CodeId = Code.CodeId 
     INNER JOIN CodeHierarchy 
      ON Customer.CodeId = CodeHierarchy.ConditionCode 
      AND Customer.CodeId != CodeHierarchy.DropCode 

Я попробовал подзапрос (не имеющего этот код), который завершил удаление всех DropCodes, независимо от того, имел ли член или не имел квалификационной иерархии (то есть строки клиентов с B не возвращались, даже если они не были t t A)

У меня была идея сделать базовый запрос выше подзапроса и присоединение его с таблицей CodeHierarchy, но я застрял на том, как написать запрос:

SELECT 
    * 
FROM 
    (
     base query (with all codes) 
    ) CustomerCodesAll 
     INNER/LEFT JOIN CodeHierarchy 
      ON ? 

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

В конечном итоге это будет просмотр, на который будут направлены запросы для целей отчетности.Таблица клиентов содержит гораздо больше данных, включая dob, пол, статус компании и т. Д. Представление будет простым и вытащить все. Запросы против представления будут включать в себя, где статьи для dob, gender и т. Д.

Может ли кто-нибудь указать мне в правильном направлении?

Спасибо за любую помощь.

ответ

3
SELECT 
    Customer.CustName, 
    Code.CodeDesc 
FROM 
    Customer 
     INNER JOIN CustomerCode AS posCustomerCode 
      ON Customer.CustId = posCustomerCode.CustId 
     INNER JOIN Code 
      ON posCustomerCode.CodeId = Code.CodeId 
     LEFT JOIN CodeHierarchy 
      ON posCustomerCode.CodeId = CodeHierarchy.DropCode 

WHERE 
    CodeHierarchy.ConditionCode NOT IN (
     SELECT CodeId 
     FROM CustomerCode AS negCustomerCode 
     WHERE negCustomerCode.CustId=posCustomerCode.CustId 
    ) 
    OR CodeHierarchy.ConditionCode IS NULL 

SQLfiddle

+0

Работал как шарм. Наверное, я был слишком импозантен. Благодаря! –

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