如何从连接到左外连接的表中获取计数?

时间:2015-02-08 07:42:09

标签: sql sql-server join outer-join

我有三张桌子。测试表(AdminTest),属于用户的测试表(UserTest)和属于每个用户测试的问题表(UserTestQuestion):

AdminTest

CREATE TABLE [dbo].[AdminTest] (
    [AdminTestId]  INT            IDENTITY (1, 1) NOT NULL,
    [Title]        NVARCHAR (100) NOT NULL
    CONSTRAINT [PK_AdminTest] PRIMARY KEY CLUSTERED ([AdminTestId] ASC));

UserTest

CREATE TABLE [dbo].[UserTest] (
    [UserTestId]    INT      IDENTITY (1, 1) NOT NULL,
    [AdminTestId]   INT      NOT NULL,
    [UserId]        INT      NOT NULL
    CONSTRAINT [PK_UT] PRIMARY KEY CLUSTERED ([UserTestId] ASC));

UserTestQuestion

CREATE TABLE [dbo].[UserTestQuestion] (
    [UserTestQuestionId]  INT              IDENTITY (1, 1) NOT NULL,
    [UserTestId]          INT              NOT NULL,
    [Answered]            BIT              DEFAULT ((0)) NOT NULL
    CONSTRAINT [PK_UQ] PRIMARY KEY CLUSTERED ([UserTestQuestionId] ASC)
);
  • AdminTest可能有也可能没有UserTest
  • UserTest将始终具有UserTestQuestions

我创建了这个SQL来从AdminTest和UserTest获取数据:

SELECT  userTest.StartedDate,
        temp.AdminTestId 
        -- AnsweredCount
        -- I want to get a count of the number of rows
        -- from the table UserTestQuestions that have
        -- the column 'Answered' set to 1 here.             
FROM
( SELECT AdminTest.AdminTestId
  FROM   AdminTest  
  JOIN   AdminTestQuestion ON  AdminTest.AdminTestId = AdminTestQuestion.AdminTestId     
GROUP BY 
  AdminTest.AdminTestId
) temp
LEFT OUTER JOIN UserTest ON  temp.AdminTestId = UserTest.AdminTestId
-- I want the above join to only join those UserTest tables that 
-- have a value of UserId set to for example 25

但现在我被困住了,有两件事我需要帮助。

  • 我只需要能够显示属于给定UserId的用户测试
  • 我需要报告UserTests中已将Answered设置为1的行数。

有人可以就如何将此功能添加到我的SQL中给出建议吗?

以下是我需要的一个例子:

AdminTestId   UserTestStartedData  AnsweredCount

1             1/1/2001             25
2             2/2/2002             10
3                
4             4/4/2004             10

1 个答案:

答案 0 :(得分:2)

加入UserTestQuestion表,并使用Conditional Aggregate仅在answered = 1

时计算
SELECT userTest.StartedDate,
       temp.AdminTestId,
       Count(CASE
               WHEN UT.answered = 1 THEN 1
             END) cnt
FROM   (SELECT AdminTest.AdminTestId
        FROM   AdminTest
               JOIN AdminTestQuestion
                 ON AdminTest.AdminTestId = AdminTestQuestion.AdminTestId
        GROUP  BY AdminTest.AdminTestId) temp
       INNER JOIN UserTest
                    ON temp.AdminTestId = UserTest.AdminTestId
       INNER JOIN [UserTestQuestion] UT
               ON UserTest.UserTestId = UT.UserTest 
       Where  UserTest.UserTestId = 25

此外,如果您希望加入仅加入那些UserTest表 值为UserId=25,然后left join将转换为Inner join

更新:

SELECT A.StartedDate,
       temp.AdminTestId,
       Count(CASE
               WHEN A.answered = 1 THEN 1
             END) cnt
FROM   (SELECT AdminTest.AdminTestId
        FROM   AdminTest
               JOIN AdminTestQuestion
                 ON AdminTest.AdminTestId = AdminTestQuestion.AdminTestId
        GROUP  BY AdminTest.AdminTestId) temp
       LEFT OUTER JOIN (SELECT userTest.StartedDate,
                               UT.answered,
                               UserTest.AdminTestId
                        FROM   UserTest
                               INNER JOIN [UserTestQuestion] UT
                                       ON UserTest.UserTestId = UT.UserTest
                        WHERE  UserTest.UserTestId = 25) A
                    ON temp.AdminTestId = A.AdminTestId 
Group by A.StartedDate,temp.AdminTestId