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,