Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 根据条件从表中选择计数_Mysql_Sql_Sql Server - Fatal编程技术网

Mysql 根据条件从表中选择计数

Mysql 根据条件从表中选择计数,mysql,sql,sql-server,Mysql,Sql,Sql Server,我有这样一个审计表: 我需要得到用户和他们签署的文档数量。一个用户可以对文档进行n次签名,但当计数时,该用户已对文档进行了1次签名。如果在一个文档上调用了reject,则该文档不考虑所有用户先前的reject。此外,查询性能非常重要,因为有数百万个条目 结果将是: 这是你想要的吗 select user, sum(case when event = 'sign' then 1 else 0 end) as num_signs from audittable group by user; 对不起

我有这样一个审计表:

我需要得到用户和他们签署的文档数量。一个用户可以对文档进行n次签名,但当计数时,该用户已对文档进行了1次签名。如果在一个文档上调用了reject,则该文档不考虑所有用户先前的reject。此外,查询性能非常重要,因为有数百万个条目

结果将是:

这是你想要的吗

select user, sum(case when event = 'sign' then 1 else 0 end) as num_signs
from audittable
group by user;

对不起,如果有错别字。我不会检查拼写。但我的想法是使用拒绝事件获取记录的最新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;

您可以为每一行创建一个名为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的详细信息 而MySQL的 编辑

请参阅有关SQL Server的详细信息
MySQL的表:更新了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

因为您标记了MySQL和SQL server MSSQL,或者您需要有效的ANSI SQL跨数据库查询,所以使用哪种SQL方言?我主要需要SQL server的查询,但在MySQL中也是OK的。此查询将给出anna | 1而不是anna | 0。。Paul拒绝了Anna的签名活动,因为doc_id=10。至少我是这样理解他的问题的。这不起作用,你不能用“拒绝事件”计算所有记录的最新id的文档,因为一个文档的拒绝不应该影响另一个文档的用户数。@trokiize它不计算“拒绝事件”但在上次拒绝之后的记录!看见它使用括号中的reject select语句获取最后一条记录的编号,然后在id>select…之后对记录进行计数。。。。所有这些记录都将被签署,而不是rejected@trokiize对于您的示例,请选择id。。。限制1将返回3。将使用此编号:在主select语句中只考虑id>3的记录,但返回的编号不适合此问题,因为您的编号基于上次拒绝,但此表包含n个文档,因此,每个文档都在不同的id上有其最后一次拒绝。您的方法只检查最后一次拒绝,并且忽略拒绝之前的所有文档,这不是我想要的。当所有文档都签名后,它将为所有文档返回0users@trokiize我完全忽略了你努力的明显部分。请看我的更新。我添加了检查,以查看是否没有拒绝,然后针对该条件执行标准的group by语句。我再次测试了它,似乎并不是在所有情况下都有效。我还更新了我的帖子,看一看。@trokiize我已经应用了一个新的修订版来解释其他事件,如“创建”。我相信我在24分钟前用'distinct'-level3looper提高了关注度。这一次,如果一个用户签署了相同的文档4次,结果是1,这是好的,但是如果一个用户签署了4个不同的文档,结果又是1,这是不好的。我已经更新了我的帖子。对于最初的问题,你的回答很接近。你能再解决一下吗?当一个用户在同一份文件上签了三次名时,应该只算一次,因为你的答案似乎涵盖了所有情况。谢谢
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')
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