我有一个这样的审核表:
id doc_id datetime user event
---|------|------------|--------|--------
1 | 10 | 04/03/2018 | john | sign
2 | 10 | 05/03/2018 | anna | sign
3 | 10 | 11/03/2018 | paul | reject
4 | 10 | 23/03/2018 | marc | sign
5 | 11 | 23/03/2018 | john | sign
6 | 11 | 24/03/2018 | luke | create
7 | 11 | 24/03/2018 | john | sign
我需要获取用户及其签名文件的数量。用户可以签名文档n次,但计数时用户已经签名1次。如果在一个文档上调用了拒绝,则该文档不会考虑所有用户先前的拒绝。此外,查询性能也非常重要,因为有数百万个条目。
结果将是:
user num_of_signed_docs
-----|-------------------|
john | 1 |
marc | 1 |
答案 0 :(得分:1)
您为每一行创建一个虚拟列,名为type
,并应用您想要的条件,
值为0或1并对其求和:
select t.username, sum(t.type) num_of_signed_docs from (
select a.username,
case
when event = 'reject' then 0
when exists
(select 1 from audit where doc_id = a.doc_id and
datetime > a.datetime and event = 'reject')
then 0
else 1 end as type
from audit a
) t
group by t.username
有关SQL Server,请参见demo
和demo for MySQL
编辑
select a.username, count(distinct a.doc_id) num_of_signed_docs
from audit a
where
a.event = 'sign'
and
not exists (
select 1 from audit where
doc_id = a.doc_id and datetime > a.datetime and event = 'reject'
)
group by a.username
答案 1 :(得分:0)
这是您想要的吗?
select user, sum(case when event = 'sign' then 1 else 0 end) as num_signs
from audittable
group by user;
答案 2 :(得分:0)
对不起,如果有错别字。我无法检查拼写。但是我的想法是获取带有拒绝事件的最新记录ID,并对表的其余部分进行操作。要优化查询,您可以将此ID存储在变量中。
SELECT user, COUNT(event = 'sign') AS `num_of_signed_docs`
FROM audittable
WHERE `id` > (SELECT `id` FROM audittable
WHERE `event` = 'reject'
ORDER BY `id` DESC LIMIT 1)
GROUP BY user;
答案 3 :(得分:0)
表:更新#3-是否将所有内容放在一起?
Create Table signed
(
id Int,
doc_id Int,
dt Datetime,
usr VarChar(25),
event VarChar(25)
)
Insert Into signed Values
(1,10,'2018/03/04','john','sign'),
(2,10,'2018/03/05','anna','sign'),
(3,10,'2018/03/11','paul','reject'),
(4,10,'2018/03/23','marc','sign'),
(5,11,'2018/03/23','john','sign'),
(6,10,'2018/03/24','luke','create'),
(7,11,'2018/03/24','john','sign')
TSQL:
if Not Exists
(Select Top 1 dt From signed Where event = 'reject')
With cte1 As
(Select id as rid,doc_id,usr, count(*) As numb From signed
Where event = 'sign'
Group by id,doc_id,usr
), cte2 As
( Select distinct usr, doc_id From cte1 )
Select usr, Count(doc_id) As num From cte2
Group By usr
Else
With cte3 As
(
Select id, doc_id, usr, count(*) As numb From signed
Where dt > (Select Top 1 dt From signed Where event = 'reject') And event = 'sign'
Group by id,doc_id,usr
), cte4 As
( Select distinct usr, doc_id From cte3 )
Select usr, Count(doc_id) As num From cte4
Group By usr
结果:
usr numb
john 1
marc 1