从复杂的数据库结构输出结果(SQL Server)

时间:2009-08-07 12:37:15

标签: sql-server tsql

这将是一个很长的问题,所以我会尽力解释它。

我开发了一个简单的报告工具,其中存储了许多结果并给出了报告ID,这些结果是从主系统上使用的特定报价生成的,其中大量的列表存储在报价表。以下是当前批次:

报告

REP_ID    DESC            QUOTE_ID
-----------------------------------
1         Test            1
2         Today           1
3         Last Week       2

结果

RES_ID    TITLE           REFERENCE          REP_ID
---------------------------------------------------
1         Equipment       Toby               1
2         Inventory       Carl               1
3         Stocks          Guest              2
4         Portfolios      Guest              3

QUOTE

QUOTE_ID     QUOTE
------------------------------------
1             Booking a meeting room
2             Car Park Policy
3             New User Guide

到目前为止,这么好,一个简单的存储过程能够提取所有必要的信息。

现在,功能列表已经提升,包括引号的类别和组。在报告表格中,quote_id已更改为group_id以链接到以下表格。

REPORTS
- REPORT_ID
- DESC
- GROUP_ID

GROUP
 - GROUP_ID
 - GROUP

GROUP_CAT_JOIN
 - GCJ_ID
 - CAT_ID
 - GROUP_ID

CATEGORIES
 - CAT_ID
 - CATEGORY

CAT_QUOTE_JOIN
 - CQJ_ID
 - CAT_ID
 - QUOTE_ID

这些更改的想法是,我现在应该为一个组写一个报告,而不是在报价上运行报告,其中组是某些场合的一组报价。我还应该能够运行一个类别的报告,其中类别也是某些部门的一组报价。诀窍是几个类别可以归入一个组。

为了进一步说明,结果表有一个链接到报告的report_id,报告有一个group_id链接到组,组和类别通过group_cat_join表链接,相同的类别和引号通过cat_quote_join表。< / p>

在基本术语中,我应该能够从一组引号或一类引号中提取所有结果。该查询旨在从特定类别,组或两者下的某个报告中提取所有结果。这个难题让我感到难过,因为内部联接似乎没有起作用,我正在努力寻找其他方法来使用SQL来解决问题。

这里有人可以帮助我吗?


这是一些额外的澄清。

我希望能够在一个类别中返回所有结果,但截至目前,下面的解决方案和我尝试过的解决方案始终输出描述中的每个解决方案,这不是我想要的。

这是我目前所拥有的数据的一个例子

结果

RES_ID    TITLE           REFERENCE          REP_ID
---------------------------------------------------
1         Equipment       Toby               1
2         Inventory       Carl               1
3         Stocks          Guest              2
4         Portfolios      Guest              3

报告

REP_ID    DESC            GROUP_ID
-----------------------------------
1         Test            1
2         Today           1
3         Last Week       2

GROUP_ID     GROUP
---------------------------------
1            Standard
2            Target Week

GROUP_CAT_JOIN

GCJ_ID       GROUP_ID     CAT_ID
----------------------------------
1            1            1
2            1            2
3            2            3

分类

CAT_ID        CAT
-------------------------------
1             York Office
2             Glasgow Office
3             Aberdeen Office

CAT_QUOTE_JOIN

CQJ_ID       CAT_ID      QUOTE_ID
-----------------------------------
1            1           1
2            2           2
3            3           3

QUOTE

QUOTE_ID     QUOTE
------------------------------------
1             Booking a meeting room
2             Car Park Policy
3             New User Guide

这是我目前正在使用的测试数据,据我所知,它与完成后将要运行的测试数据类似。老实说,我仍然试图了解这个结构。

我正在寻找的结果是,如果我选择按组搜索,我将获得组内的所有内容,如果我选择一个类别中的所有内容,我会在该类别中获取所有内容,如果我选择某个类别中的内容一个小组,我把所有内容都归入该类别。目前的问题是,无论何时引用该组,都会拉出与该组相关联的每个类别中的所有内容。

2 个答案:

答案 0 :(得分:1)

以下内容将从results获取必要的行:

select
    a.*
from
    results a
    inner join reports b on
        a.rep_id = b.rep_id
        and (-1 = @GroupID or 
            b.group_id = @GroupID)
        and (-1 = @CatID or
            b.cat_id = @CatID)

请注意,我使用-1作为所有群组和类别的占位符。显然,使用对您有意义的值。但是,通过这种方式,您可以指定特定的group_id或特定的cat_id,并获得所需的结果。

此外,如果您想要群组/类别/报价详细信息,您可以随时添加更多inner join来获取该信息。

另请注意,我已将Group_IDCat_ID条件添加到Reports表中。当且仅当您向Cat_ID表添加Reports列时,这将是必需的SQL。我知道你当前的表结构不支持这个,但它需要。否则,正如我的祖父常说的那样,“男孩,你不能从这里到达那里。”这里的问题是,您希望reports group限制category,但reports 知道group。因此,我们需要将某些内容绑定到category reports。否则,它永远不会永远限制reports categorygroup category唯一可以限制的是引号。这似乎不是你的要求。

作为附录:如果您将cat_id添加到results而不是reports,则加入条件应为:

    and (-1 = @CatID or
        a.cat_id = @CatID)

答案 1 :(得分:0)

这是你在找什么?

SELECT a.* 
FROM Results a
JOIN Reports b ON a.REP_Id = c.REP_Id
WHERE EXISTS (
    SELECT * FROM CAT_QUOTE_JOIN c
    WHERE c.QUOTE_ID = b.QUOTE_ID -- correlation to the outer query
      AND c.CAT_ID = @CAT_ID -- parameterization
    )
   OR EXISTS (
    -- note that subquery table aliases are not visible to other subqueries
    -- so we can reuse the same letters
    SELECT * FROM CAT_QUOTE_JOIN c, GROUP_CAT_JOIN d 
    WHERE c.CAT_ID = d.CAT_ID -- subquery join
      AND c.QUOTE_ID = b.QUOTE_ID -- correlation to the outer query
      AND d.GROUP_ID = @GROUP_ID -- parameterization
    )