Sql 如何从联接到左外部联接的表中获取计数?

Sql 如何从联接到左外部联接的表中获取计数?,sql,sql-server,join,outer-join,Sql,Sql Server,Join,Outer Join,我有三张桌子。测试表(AdminTest)、属于用户的测试表(UserTest)和属于每个用户测试的问题表(UserTestQuestion): 行政测试 CREATE TABLE [dbo].[AdminTest] ( [AdminTestId] INT IDENTITY (1, 1) NOT NULL, [Title] NVARCHAR (100) NOT NULL CONSTRAINT [PK_AdminTest] PRIMAR

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

行政测试

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

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));
用户测试问题

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总是有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
  • 我需要报告UserTests中回答设置为1的行数
有人能给我一些关于如何将此功能添加到我的SQL的建议吗

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

AdminTestId   UserTestStartedData  AnsweredCount

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

加入
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
另外,如果希望join仅联接那些 如果值为
UserId=25
,则
左连接
将转换为
内部连接

更新:

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

非常感谢。现在我将尝试一下。我想显示所有AdminTest表,以及那些存在的userTest表(具有相同的AdminTestId)和UserId=25。是否有一种方法可以保留左外部联接,并添加一个WHERE,将UserTest表限制为具有25个userid的表?我认为我仍然需要左外部联接,因为我想显示一个管理表列表,即使没有用户表。我只是在问题中添加了一个输出示例。我希望它能让我明白一点。我想你的最新更新已经接近我需要的了,但我还是发现了一个错误。我接受了你给我的代码,运行了它,我已经在问题中添加了代码和错误消息,这样你就可以看到消息是什么。我在底部附近做了一些小改动(UserTest>UserTestId),我还将WHERE中的检查设置为1=1,这样我就可以轻松地进行测试。希望您对错误消息有一些想法。你认为回答=1的问题的计数应该在代码末尾8行的最后一个选择中进行吗?非常感谢。现在可以了!只是一个小问题。我看到你正在计算A.在最外层选择中的应答时间。您认为如果在以“LEFT-OUTER-JOIN(select-userTest.StartedDate)”开头的最内层选择中执行此操作会更有效吗?