建立每个人在散步时所处位置的迷你排行榜



我的"Walks"DB有以下一组简单的SQL Server表:

CREATE TABLE [USERS] (
[USERID] INT NOT NULL IDENTITY,
[USERNAME] NVARCHAR(50),
PRIMARY KEY ([USERID])
)
CREATE TABLE [GROUPS] (
[GID] INT NOT NULL IDENTITY,
[GNAME] NVARCHAR(50),
PRIMARY KEY ([GID])
)
CREATE TABLE [GROUPWALKERS] (
[GWID] INT NOT NULL IDENTITY,
[GID] INT DEFAULT 0,
[USERID] INT DEFAULT 0,
PRIMARY KEY ([GWID])
)
CREATE TABLE [WALKS] (
[WID] INT NOT NULL IDENTITY,
[WNAME] NVARCHAR(50),
[WORDER] INT DEFAULT 0,
PRIMARY KEY ([WID])
)
CREATE TABLE [CURRENTSITU] (
[CSID] INT NOT NULL IDENTITY,
[USERID] INT DEFAULT 0,
[WID] INT DEFAULT 0,
[GID] INT DEFAULT 0,
[STARTTIME] DATETIME,
[ENDTIME] DATETIME,
PRIMARY KEY ([CSID])
)

这些表背后的思想是USERS表存储使用我的DB的人。

GROUPS表存储行走组名称,GROUPWARKERS表存储哪些用户在哪个组中。

WALKS表包含步行以及人们应该步行的顺序。

CURRENTSITE表持续记录每个用户步行的位置。它将包含每个用户id/步行id的单行,例如:

CSID   USERID     WID    GID   STARTTIME         ENDTIME
1      35         2      2     2021-05-16 09:15
2      36         1      2     2021-05-16 08:30
3      37         2      2     2021-05-16 08:00

有一个用户ID 38和39,但他们还没有开始任何步行

插入的示例有:

SET IDENTITY_INSERT USERS ON
INSERT INTO USERS (USERID,USERNAME) VALUES (35,'Bill')
INSERT INTO USERS (USERID,USERNAME) VALUES (36,'Bob')
INSERT INTO USERS (USERID,USERNAME) VALUES (37,'Jill')
INSERT INTO USERS (USERID,USERNAME) VALUES (38,'Jean')
INSERT INTO USERS (USERID,USERNAME) VALUES (39,'Jack')
SET IDENTITY_INSERT USERS OFF
SET IDENTITY_INSERT GROUPS ON
INSERT INTO GROUPS (GID,GNAME) VALUES (1,'Group 1')
INSERT INTO GROUPS (GID,GNAME) VALUES (2,'Group 2')
SET IDENTITY_INSERT GROUPS OFF
SET IDENTITY_INSERT GROUPWALKERS ON
INSERT INTO GROUPWALKERS (GWID,GID,USERID) VALUES (1,2,35)
INSERT INTO GROUPWALKERS (GWID,GID,USERID) VALUES (2,2,36)
INSERT INTO GROUPWALKERS (GWID,GID,USERID) VALUES (3,2,37)
INSERT INTO GROUPWALKERS (GWID,GID,USERID) VALUES (4,2,38)
INSERT INTO GROUPWALKERS (GWID,GID,USERID) VALUES (5,2,39)
SET IDENTITY_INSERT GROUPWALKERS OFF
SET IDENTITY_INSERT WALKS ON
INSERT INTO WALKS (WID,WNAME,WORDER) VALUES (1,'Snowdon',0)
INSERT INTO WALKS (WID,WNAME,WORDER) VALUES (2,'Bluebell Wood',1)
INSERT INTO WALKS (WID,WNAME,WORDER) VALUES (3,'Mam Tor',2)
INSERT INTO WALKS (WID,WNAME,WORDER) VALUES (4,'River Seven',3)
INSERT INTO WALKS (WID,WNAME,WORDER) VALUES (5,'Scar Fell',4)
SET IDENTITY_INSERT WALKS OFF
SET IDENTITY_INSERT CURRENTSITU ON
INSERT INTO CURRENTSITU (CSID,USERID,WID,GID,STARTTIME,ENDTIME) VALUES (1,35,2,2,'2021-05-16 09:15',NULL)
INSERT INTO CURRENTSITU (CSID,USERID,WID,GID,STARTTIME,ENDTIME) VALUES (2,36,1,2,'2021-05-16 08:30',NULL)
INSERT INTO CURRENTSITU (CSID,USERID,WID,GID,STARTTIME,ENDTIME) VALUES (3,37,2,2,'2021-05-16 08:00',NULL)
SET IDENTITY_INSERT CURRENTSITU OFF

现在我想做的是一个每个人在散步时所处位置的迷你排行榜,所以我尝试了:

select g.GID, u.USERID, w.WORDER, cs.STARTTIME 
from GROUPS g
left join GROUPWALKERS gw on g.GID=gw.GID 
left join CURRENTSITU cs on cs.GID=g.GID 
left join WALKS w on cs.WID=w.WID 
inner join USERS u on gw.USERID=u.USERID  
where g.GID = 2 
order by w.WORDER, cs.STARTTIME, u.USERID

以上是尝试获取组id、用户id、他们按预定义顺序进行的行走以及当前行走的开始时间。然后我做一个简单的"排序依据"来创建我的表。

我的问题是,即使我尝试过绕过连接和/或使用不同的连接,我仍然无法获得:

GID    USERID    WORDER     STARTTIME  
2      37        2          2021-05-16 08:00
2      35        2          2021-05-16 09:15
2      36        1          2021-05-16 08:30
2      38        NULL       NULL
2      39        NULL       NULL

我得到:

GID    USERID    WORDER     STARTTIME  
2      37        2          2021-05-16 08:00
2      35        2          2021-05-16 08:00
2      36        2          2021-05-16 08:00
2      38        2          2021-05-16 08:00
2      39        2          2021-05-16 08:00

或者我得到了所有的用户,但进行了其他行走的用户显示了他们其他行走的开始时间。只有完全没有进行漫游的用户才会显示WORDER和STARTTIME为Null的

有什么想法吗?

感谢

列键有点令人困惑。可能想更详细地命名它们。注意使用哪个表作为基础(FROM子句(。从Groups和GroupStats开始,您实际上是在首先询问这些详细信息,然后询问用户信息(如果可用(。一种更直接的方法是思考您的查询希望实现什么,这主要是关于用户的统计图。

由于这是所需的数据,我会从Users开始,然后加入他们的组成员资格,然后加入组详细信息,然后组活动,并将详细信息数据作为LEFT OUTER join进行遍历,因为如果存在,您希望返回他们的数据,如果不存在,则返回NULL。

SELECT  g.GID
,u.USERID
,w.WORDER
,c.STARTTIME
FROM    dbo.USERS                       AS u
INNER JOIN dbo.GROUPWALKERS     AS g ON g.USERID = u.USERID
INNER JOIN dbo.GROUPS           AS g2 ON g2.GID = g.GID
LEFT OUTER JOIN dbo.CURRENTSITU AS c ON c.USERID = u.USERID
AND c.GID = g.GID
LEFT OUTER JOIN dbo.WALKS       AS w ON w.WID = c.WID;

最新更新