【问题标题】:Inner Join with two tables, and Left Join the result with another table两个表的内连接,另一个表的左连接结果
【发布时间】:2020-09-07 16:41:38
【问题描述】:

我想从三个表中查询数据,Inner Join 查询两个表,Left Join 查询另一个表的结果。

我在这里要做的是获取 UserTableActivity 中的所有记录,如果项目在活动完成表中,则增加记录的计数,否则将其值设为第 0 项。

并从 ActivityCompletion 和 Activity 表中计算 ItemCompletedItemRemaining

期望的输出:

ActivityDuration |  Name    |ItemCompleted |ItemRemaining
-----------------|----------|--------------|-------------
Week 7           |  A B     |   2          |    3
Week 7           |  A C     |   1          |    4
Week 7           |  A C A C |   0          |    5
Week 7           |  A C B   |   1          |    4
Week 7           |  A C C   |   2          |    3
Week 7           |  A C D   |   2          |    3
Week 7           |  A C E   |   2          |    3
Week 7           |  A C F   |   2          |    3
Week 8           |  A B     |   0          |    3
Week 8           |  A C     |   0          |    3
Week 8           |  A C A C |   0          |    3
Week 8           |  A C B   |   1          |    2
Week 8           |  A C C   |   2          |    0
Week 8           |  A C D   |   0          |    3
Week 8           |  A C E   |   0          |    3   
Week 8           |  A C F   |   0          |    3
Week 9           |  A B     |   3          |    0
Week 9           |  A C     |   1          |    2
Week 9           |  A C A C |   1          |    2
Week 9           |  A C B   |   0          |    3
Week 9           |  A C C   |   0          |    3
Week 9           |  A C D   |   0          |    3
Week 9           |  A C E   |   0          |    3
Week 9           |  A C F   |   0          |    3
                             

样本记录:

create table UserTable (
  Id integer not null,
  Name varchar(12) not null
);

insert into UserTable  values (1,  'A B');
insert into UserTable  values (2,  'A C');
insert into UserTable  values (3,  'A C A C');
insert into UserTable  values (4,  'A C C');
insert into UserTable  values (5,  'A C B');
insert into UserTable  values (6,  'A C C');
insert into UserTable  values (7,  'A C D');
insert into UserTable  values (8,  'A C E');
insert into UserTable  values (9,  'A C F');


create table Activity (
  Id integer not null,
  Activity varchar(12) not null,
  ActivityDuration varchar(12) not null,
);

insert into Activity  values (1, 'Videos', 'Week 9');
insert into Activity  values (2, 'Text',   'Week 9');
insert into Activity  values (3, 'Page',   'Week 9');
insert into Activity  values (6, 'Chat',   'Week 8');
insert into Activity  values (11, 'Image', 'Week 8');
insert into Activity  values (12, 'Chat',  'Week 8');
insert into Activity  values (13, 'Chat',  'Week 7');
insert into Activity  values (17, 'Vidoes','Week 7');
insert into Activity  values (18, 'Vidoes','Week 7');
insert into Activity  values (19, 'Chat',  'Week 7');
insert into Activity  values (19, 'Chat',  'Week 7');


create table ActivityCompletion (
  Id integer not null,
  UserId integer not null,
  ActivityId integer not null,
);
insert into ActivityCompletion  values (1,  1 , 1); --A B --Week 9
insert into ActivityCompletion  values (2,  1 , 2); --A B --Week 9 
insert into ActivityCompletion  values (3,  1 , 3); --A B --Week 9
insert into ActivityCompletion  values (4,  2 , 2); --A C --Week 9
insert into ActivityCompletion  values (5,  3 , 2); --A C A C --Week 9
insert into ActivityCompletion  values (6,  4 ,13); --A C C --Week 7
insert into ActivityCompletion  values (7,  7 ,13); --A C D --Week 7
insert into ActivityCompletion  values (7,  7 ,13); --A C D --Week 7
insert into ActivityCompletion  values (7,  8 ,13); --A C E --Week 7
insert into ActivityCompletion  values (7,  8 ,18); --A C E --Week 7
insert into ActivityCompletion  values (10, 9 ,18); --A C F--Week 7
insert into ActivityCompletion  values (11, 9 ,13); --A C F--Week 7
insert into ActivityCompletion  values (12, 4 ,13); --A C C--Week 7
insert into ActivityCompletion  values (13, 5 ,18); --A C B--Week 7 
insert into ActivityCompletion  values (14, 5 ,11); --A C B--Week 8
insert into ActivityCompletion  values (15, 2 ,13); --A C --Week 7
insert into ActivityCompletion  values (16, 1 ,13); --A B --Week 7
insert into ActivityCompletion  values (17, 1 ,13); --A B --Week 7
insert into ActivityCompletion  values (18, 6 ,11); --A C C --Week 8
insert into ActivityCompletion  values (19, 6 ,11); --A C C--Week 8

我试过的是:

SELECT AT.ActivityDuration,  UA.Name, COUNT(AT.Activity) ItemCompleted
FROM dbo.Activity AT 
LEFT JOIN  (select UT.Name, UT.Id, AC.ActivityId from UserTable UT
  INNER JOIN ActivityCompletion AC ON UT.Id = AC.UserId
) UA ON UA.ActivityId = AT.Id
GROUP BY AT.ActivityDuration, UA.Name
ORDER BY AT.ActivityDuration

我无法找到此查询未返回正确值的原因。我错过了什么?

https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=8b5439f8d627c25596ed1cfc767837ef

【问题讨论】:

    标签: sql sql-server group-by count left-join


    【解决方案1】:

    我认为这是用户和活动之间的自我加入,然后是left join 带来已完成的活动,最后是聚合:

    select a.activityDuration , u.name, count(ac.id) itemCompleted, count(*) - count(ac.id) itemRemaining
    from usertable u
    cross join activity a
    left join activityCompletion ac 
        on  ac.userid = u.id
        and ac.activtyid = a.activtyid
    group by u.id, u.name, a.activityDuration 
    

    【讨论】:

    • 所以在这个查询之外应该有另一个聚合?
    • @AkshayKriti:这个查询应该会产生你期望的结果,不需要在其他查询中包含它。
    • dbfiddle.uk/… 在提琴手这里为什么我得到 90 个结果,为什么查询没有聚合?
    • @AkshayKriti:小提琴中的查询在group by 中多了一列,就像我的查询一样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多