如果没有记录表明组中的用户已注销,我将尝试插入一个条目。
declare @test table (grp varchar(2),logged varchar(4),time datetime)
insert into @test (grp,logged,time)
values ('A1', 'IN','20181111 09:00:00')
,('A1', 'OUT','20181111 10:00:00')
,('A2', 'IN','20181111 09:10:00')
,('A2', 'IN','20181111 09:20:00')
,('A3', 'IN','20181111 09:30:00')
,('A3', 'OUT','20181111 10:30:00')
期望的输出
+-----+--------+-------------------------+
| grp | logged | time |
+-----+--------+-------------------------+
| A1 | IN | 2018-11-11 09:00:00.000 |
| A1 | OUT | 2018-11-11 10:00:00.000 |
| A2 | IN | 2018-11-11 09:10:00.000 |
| A2 | IN | 2018-11-11 09:20:00.000 |
| A2 | OUT | NULL |
| A2 | OUT | NULL |
| A3 | IN | 2018-11-11 09:30:00.000 |
| A3 | OUT | 2018-11-11 10:30:00.000 |
| A4 | IN | 2018-11-11 09:40:00.000 |
| A4 | OUT | NULL |
+-----+--------+-------------------------+
有什么想法吗?
最佳答案
我有两个版本给你
CREATE TABLE SignIn(grp varchar(10), logged varchar(3), [time] datetime)
INSERT INTO SignIn
VALUES
('A1','IN' , '2018-11-11 09:00:00.000' ),
('A1','OUT', '2018-11-11 10:00:00.000' ),
('A2','IN' , '2018-11-11 09:10:00.000' ),
('A2','IN' , '2018-11-11 09:20:00.000' ),
('A3','IN' , '2018-11-11 09:30:00.000' ),
('A3','OUT', '2018-11-11 10:30:00.000' ),
('A4','IN', '2018-11-11 09:40:00.000' )
这个版本正如您所期望的那样。对于每条记录,您将获得一份 OUT 副本
INSERT INTO SignIn (grp, logged, time)
SELECT s.grp, 'OUT', NULL
FROM SignIn s
INNER JOIN (
SELECT grp
FROM SignIn
GROUP BY grp
HAVING MAX(CASE WHEN Logged = 'OUT' THEN 1 ELSE 0 END) = 0
) notSignedOut ON s.grp = notSignedOut.grp
但是,如果您不想要重复的记录,并且只想为该组提供一条记录,您可以使用以下选项:
INSERT INTO SignIn (grp, logged, time)
SELECT grp, 'OUT', NULL
--ISLoggedOut = MAX(CASE WHEN Logged = 'OUT' THEN 1 ELSE 0 END)
FROM SignIn
GROUP BY grp
HAVING MAX(CASE WHEN Logged = 'OUT' THEN 1 ELSE 0 END) = 0
主要逻辑隐藏在 ISLoggedOut = MAX(CASE WHEN Logged = 'OUT' THEN 1 ELSE 0 END) 下。对于每组记录,我添加了是否有记录的指示器。如果没有 - 值将为 0。
另一种选择是使用不存在子句
INSERT INTO SignIn (grp, logged, time)
SELECT s.grp, 'OUT', NULL
FROM SignIn s
WHERE NOT EXISTS (SELECT TOP 1 1 FROM SignIn i WHERE i.grp = s.grp AND Logged = 'OUT')
我个人更喜欢使用HAVING,根据一些经验,对于大表来说,它有时会更快。 例如对于我们的示例语句,having 会生成下一个统计数据
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. Table 'SignIn'. Scan count 2, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
并存在语句:
Table 'SignIn'. Scan count 2, logical reads 8, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
看起来 HAVING 语句的读取次数比 EXISTS 少
关于sql - TSQL - 如果组内不存在特定条目,则插入条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53407943/