构建不包含基于层次结构的数据的SQL查询

时间:2013-04-24 19:57:56

标签: sql sql-server sql-server-2008-r2

过去几天我在Google和SO上度过了相当多的时间,但我似乎无法找到问题的答案。不知道如何将问题说成一个合理的问题会让它变得更加困难。你不知道你不知道什么,对吗?

由于业务限制,我无法发布我的确切代码和数据库结构,所以我会尽力给出一个可靠的例子。

客户表 - 保留客户数据

[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 Table - 如果客户有ConditionCode,则不应包含的代码层次结构(DropCode)

[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.由于她也有代码B,所以代码C和D没有列在Jane 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的客户行)有A)

我有一个想法是将基本查询放在子查询上面并将它与CodeHierarchy表连接起来,但我仍然坚持如何编写查询:

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

我也一直在读CTE,但我不确定如何使用这种技术。

这将最终成为一个被查询以进行报告的视图。客户表包含更多数据,包括dob,性别,公司状态等。视图将很简单并且可以提取所有内容。针对视图的查询将包括dob,gender等的where子句

有人能指出我正确的方向吗?

感谢您的帮助。

1 个答案:

答案 0 :(得分: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