根据关系查询具有一对多和多对一关系的表中的数据

时间:2013-07-30 07:28:25

标签: .net sql sql-server sql-server-2008

虽然我现在使用stackoverflow很长一段时间,但这是我第一次发帖提问。我希望有人能帮我解决这个问题。

我在SQL Server 2005中有这个数据库结构(请看下面的图表),我现在正在处理使用Crystal Reports的报告。

我想要做的是从特定实施机构的数据库中获取(计数)课程,辅导员和学习者的总数(这是另一个未在此图中显示的表,仅与课程表有关系) )。

我可以使用where语句中的ImplementingAgencyID列获取课程总数,但我无法弄清楚如何获得同一机构的辅导员和学习者总数(例如,ImplementingAgencyID 1或2)。

有没有办法做到这一点?数据库中已有数千条记录,因此即使我必须将ImplementingAgencyID列添加到所有三个表中,我也无法为旧条目填充此列。它只会为新条目添加。

任何人都可以帮我解决问题吗?什么是最好的解决方案?我需要选择查询吗?

---我无法发布图片,因此我将列出下面每个表的重要列---

Courses (table):
 Id         int
 SerialNum      nvarchar
 ProvinceID     int
 DistrictID     int
 VillageID      int
 EntryUserID        uniqueidentifier
 NearestSchool      nvarchar
 ImplementingAgencyID   int
 FacilitatorID
 CourseVenueID      int
 ...

Learners (table):
 Id
 CourseID
 LearnerName
 ...

Facilitators (table):
 Id
 SerialNum
 FullName
 Age
 ProvinceID
 DistrictID
 VillageID
 ...

Agencies (table):
  Id
  AgencyNameLocal
  AgencyNameEnglish
  ...

关系: 1:Courses表中的ImplementingAgencyID列与Agencies表中的Id列具有多对一关系。

2:Learners表中的CourseID列与Courses表中的Id列具有多对一关系。

3:Courses表中的FacilitatorID列与Facilitators表中的Id列具有多对一关系。

3 个答案:

答案 0 :(得分:1)

我希望我能正确理解你。 对于每个机构,您想知道每种类型的单元(学习者,辅导员,课程)有多少。

此查询应该执行您想要执行的操作:

;WITH data 
     AS (SELECT T1.*, 
                T2.FULLNAME AS Facil_Name, 
                T3.ID       AS Learner_Name, 
                T4.AGENCYNAME 
         FROM   COURSES T1 
                INNER JOIN FACILITATORS T2 
                        ON T1.FACILITATORID = t2.ID 
                INNER JOIN LEARNERS T3 
                        ON T1.ID = T3.COURSEID 
                INNER JOIN AGENCIES T4 
                        ON T1.IMPLEMENTINGAGENCYID = T4.ID) 

SELECT AGENCYNAME, 
       Count(DISTINCT FACIL_NAME) Per_Agency, 
       'Facil'                    TYPE 
FROM   data 
GROUP  BY AGENCYNAME 
UNION 
SELECT AGENCYNAME, 
       Count(DISTINCT LEARNER_NAME) Per_Agency, 
       'Learner'                    TYPE 
FROM   data 
GROUP  BY AGENCYNAME 
UNION 
SELECT AGENCYNAME, 
       Count(DISTINCT ID) Per_Agency, 
       'Course'           TYPE 
FROM   data 
GROUP  BY AGENCYNAME 
ORDER  BY TYPE 

您可以在SQL Fiddle找到一个有效的例子 如果您有任何问题,请发表评论。

答案 1 :(得分:1)

您似乎想要group bycount distinct

的组合
select
    implementingagencyid,
    count (distinct courses.id) as CourseCount,
    count (distinct learners.id) as LearnerCount,
    count (distinct facilitators.id) as FacilitatorCount
courses
    inner join learners on courses.ID = learners.courseid
    inner join facilitators on courses.facilitatorID = facilitators.id
    inner join agencies on courses.implementingagencyid = agencies.id    
group by
    implementingagencyid

答案 2 :(得分:1)

对于课程,您可以计算某个代理机构的行数(我在这里使用数字77):

SELECT COUNT(*)
FROM courses
WHERE ImplementingAgencyID = 77

对于辅导员,您可以计算FacilitatorID的不同值的出现次数

SELECT COUNT(DISTINCT FacilitatorID)
FROM courses
WHERE ImplementingAgencyID = 77

对于学习者,你必须加入课程和学习者表,但是你可以再次计算

SELECT COUNT(DISTINCT l.id)
FROM courses c JOIN learners l ON c.id = l.CourseID
WHERE ImplementingAgencyID = 77

请参阅http://sqlfiddle.com/#!2/59a68/4来玩。