Sql 以及跨群体的聚合。或者换句话说,在一个查询中有两组不同的groupby(我不想在这里提到UNION,mkay?)

Sql 以及跨群体的聚合。或者换句话说,在一个查询中有两组不同的groupby(我不想在这里提到UNION,mkay?),sql,count,firebird,firebird2.5,Sql,Count,Firebird,Firebird2.5,您需要一组groupby标准来计算具有相同日期部分(但可能不同时间部分)的行,还需要另一组groupby标准来拾取和呈现日期和时间不同的组 在简单明了的SQL1999中,这意味着您必须使用两个selects以某种方式进行两个分组,这里是Yogesh和Gordon的答案 正如Gordon在post-99 SQL中提到的,有一些窗口函数可以让您在一个select中设置这些标准集,但无论如何它们在Firebird 2.x中都不可用。似乎有一些答案建议“做什么”,但没有试图解释为什么结果是这样的。发生了

您需要一组
groupby
标准来计算具有相同日期部分(但可能不同时间部分)的行,还需要另一组
groupby
标准来拾取和呈现日期和时间不同的组

在简单明了的SQL1999中,这意味着您必须使用两个
select
s以某种方式进行两个分组,这里是Yogesh和Gordon的答案


正如Gordon在post-99 SQL中提到的,有一些窗口函数可以让您在一个
select
中设置这些标准集,但无论如何它们在Firebird 2.x中都不可用。

似乎有一些答案建议“做什么”,但没有试图解释为什么结果是这样的。发生了什么。 这似乎是一条鱼,而不是鱼竿

当我添加
count(cast(r.“When”as date))
时,它只显示一个

这有点滑稽。这一行显示了新手对自然人类语言(如英语)和数学集合语言(如SQL)之间的误解

R.Kut把这句他添加的话读作“我想计算给定表达式中有多少个[不同的]值”

但这并不是这个命令在SQL中的实际含义。在SQL中,它的意思是“我想
计算
有多少,其中
给定表达式
不为空。”

因此,
count(cast(r.“WHEN”as date))
count(r.“WHEN”)
之间实际上没有区别——这两个参数表达式要么都是
NULL
,要么都是
非NULL
。因此,这些同样可为空的参数的
count
值也相等

截断聚合函数的参数值的尝试,就像它可能改变可空性一样,是一种误解。我也在那里。这需要时间来适应数学集合上的聚合的真正含义,并且当您阅读SQL时,您不会阅读英语

坦白地说,您可以在这里执行
count(1)
操作,不仅删除类型转换,而且删除列本身-它仍然是相同的,因为这些是行,而不是要求计数的值除非存在
“WHEN”为空的行
——这将由
分组依据
而不是
计数来解释阅读并思考下一部分后,回来玩玩


现在,
count
函数还有一个参数,我在上面提到过。就是那个“独特的”参数

备注:有人可能会说,
distinct
是SQL语言的一个关键字,不是函数的参数,但事实上,而不是法律上,它改变了函数的工作方式,因此在我看来,它就是参数,以一种不同寻常的SQLish方式,参数通常被赋予函数。或者,用另一种方式来解释这一点,它可能是函数名的一部分,如果设想我们有两个函数可供选择,
count
count distinct

因此,主题启动者可以添加
count(distinct cast(r.“WHEN”as date))
,然后

…并确保没有任何变化。因为这一次他真的会对服务器说,使用NOTNULL(始终仅NOTNULL!)和
distinct
值来计算行数-在组内进行计数

这些团体是什么

group by
    r."WHEN",
    INOUT,
    u.USERNAME,
    r.UPDATEINOUT
请看,在组中,我们有不同的时间和日期值为“WHEN”的行。还有其他专栏,但我不是在关注它们。这里的问题是,在每个组中,时间和日期部分都保持相同。“相同”是指“有一个不同的值,一次又一次地重复”。如果只有一个
不同的
时间和日期值,则仅时间或仅日期的减少值将具有相同的计数(减少值只能使以前不同的值相等,但不能使以前相等的值现在不同)


当然,在其他情况下,当对未包含在组中的列进行计数时(或当根本没有
group by
子句时),结果可能不同。有
count(distinct…
可能会做主题启动者希望它做的事情

-例如

然而,我们必须记住:

  • 这是以牺牲服务器所做的额外排序和分组工作为代价的,这可能会使查询速度变慢或消耗大量内存
  • 但是,它在组中仍然有效(只有组才会开始包含不同的
    count
    ed列值)
  • …只是有时候,如果程序员没有通过添加
    groupby
    子句将其设置为不同,那么组就是整个查询结果集(最简单的变体-整个表)
上面链接的示例代码:

create table X(a integer, b integer);

insert into X values (1,1);
insert into X values (1,2);
insert into X values (1,2);

commit;

select count(distinct b) from x group by a
-- Result: 1 row: 2

-- or if the whole table is the group
select count(distinct b) from x 
-- Result: 1 row: 2

-- but if the group includes the counted column
-- then every group would contain EXACTLY ONE
-- row with a not-null distinct value
select count(distinct b) from x group by b
-- Result: 2 rows: 1 and 1

在这里,我们来到另一个修改玩具

group by
    cast(r."WHEN" as date),   -- <====
    INOUT,
    u.USERNAME,
    r.UPDATEINOUT
因为,如果您明确要求服务器将它的不同值分组,那么当行中出现
时,您就不能有
的“一个真值”


在这里,您可能会得出结论,没有简单直接的方法可以让两个组和跨组聚合。或者换句话说,在一个查询中有两组不同的
groupby
(我不想在这里提到
UNION
,mkay?)

您需要一组
groupby
标准来计算具有相同日期部分(但可能不同时间部分)的行,还需要另一组
groupby
标准来拾取和呈现组dif
count(cast(r."WHEN" as date))
with t as ( < your query here > )
select t.*, tw.cnt
from t join
     (select cast("WHEN" as date) as wdate, count(*) as cnt
      from t
      group by cast("WHEN" as date)
     ) tw
     on cast(t."WHEN" as date) = tw.wdate;
SELECT  u.USERNAME, r."WHEN", r.UPDATEINOUT,
        case (r.UPDATEINOUT) when 0 then  0 when 1 then 1 else r.INOUT end INOUT,
        (SELECT COUNT(*) 
         FROM ATTENDANT r1 
         WHERE cast(r1."WHEN" as date)) = cast(r."WHEN" as date)
        ) as Count
FROM ATTENDANT r LEFT JOIN  
     USERS u 
     ON r.USERID = u.ID 
WHERE u.USERNAME = 'rk' AND 
    (r.UPDATEINOUT = 1 or r.UPDATEINOUT = 0 or r.UPDATEINOUT is null)
GROUP BY r."WHEN", INOUT, u.USERNAME, r.UPDATEINOUT
ORDER BY r."WHEN";
group by
    r."WHEN",
    INOUT,
    u.USERNAME,
    r.UPDATEINOUT
create table X(a integer, b integer);

insert into X values (1,1);
insert into X values (1,2);
insert into X values (1,2);

commit;

select count(distinct b) from x group by a
-- Result: 1 row: 2

-- or if the whole table is the group
select count(distinct b) from x 
-- Result: 1 row: 2

-- but if the group includes the counted column
-- then every group would contain EXACTLY ONE
-- row with a not-null distinct value
select count(distinct b) from x group by b
-- Result: 2 rows: 1 and 1
group by
    cast(r."WHEN" as date),   -- <====
    INOUT,
    u.USERNAME,
    r.UPDATEINOUT
SELECT 
    u.USERNAME,  
    cast(r."WHEN" as date),  -- <=== no more raw r."WHEN"
    r.UPDATEINOUT,