名称为“count”的计数列返回多行。为啥?
Posted
技术标签:
【中文标题】名称为“count”的计数列返回多行。为啥?【英文标题】:Count column with name 'count' returns multiple rows. Why?名称为“count”的计数列返回多行。为什么? 【发布时间】:2017-08-18 08:48:26 【问题描述】:我不明白为什么这个查询:
select count(base.*) from mytable base;
确实返回多行。
select count(1) from mytable base;
返回正确的计数。
有一列名为count
。
谁能解释一下这种行为?
这是来自架构的信息:
table_catalog,table_schema,table_name,column_name,ordinal_position,column_default,is_nullable,data_type,character_maximum_length,character_octet_length,numeric_precision,numeric_precision_radix,numeric_scale,datetime_precision,interval_type,interval_precision,character_set_catalog,character_set_schema,character_set_name,collation_catalog,collation_schema,collation_name,domain_catalog,domain_schema,domain_name,udt_catalog,udt_schema,udt_name,scope_catalog,scope_schema,scope_name,maximum_cardinality,dtd_identifier,is_self_referencing,is_identity,identity_generation,identity_start,identity_increment,identity_maximum,identity_minimum,identity_cycle,is_generated,generation_expression,is_updatable
mydatabase,vcs,mytable,controlepunt,1,,YES,text,,1073741824,,,,,,,,,,,,,,,,mydatabase,pg_catalog,text,,,,,1,NO,NO,,,,,,,NEVER,,YES
mydatabase,vcs,mytable,norm,2,,YES,text,,1073741824,,,,,,,,,,,,,,,,mydatabase,pg_catalog,text,,,,,2,NO,NO,,,,,,,NEVER,,YES
mydatabase,vcs,mytable,fout,3,,YES,text,,1073741824,,,,,,,,,,,,,,,,mydatabase,pg_catalog,text,,,,,3,NO,NO,,,,,,,NEVER,,YES
mydatabase,vcs,mytable,count,4,,YES,bigint,,,64,2,0,,,,,,,,,,,,,mydatabase,pg_catalog,int8,,,,,4,NO,NO,,,,,,,NEVER,,YES
mydatabase,vcs,mytable,id,5,,YES,bigint,,,64,2,0,,,,,,,,,,,,,mydatabase,pg_catalog,int8,,,,,5,NO,NO,,,,,,,NEVER,,YES
【问题讨论】:
简单的select count(*) from mytable
有什么问题?
没什么,我只是不明白为什么会出现这种情况。
好问题。该查询甚至不是有效的 ANSI SQL 语法。
【参考方案1】:
这种风格显然被称为功能表示法。
它使table.col
和col(table)
等效。
table
和 table.*
返回同一组列。
这个问题有更多信息:Using functional notation in PostgreSQL queries instead of dot notation
在 postgresql 文档中:https://www.postgresql.org/docs/9.1/static/xfunc-sql.html
另一种选择是使用功能符号来提取属性。解释这一点的简单方法是,我们可以互换使用符号属性(表)和 table.attribute。
【讨论】:
【参考方案2】:这不是答案 - 使用它来扩展 OP 的示例。它似乎与聚合函数无关:
t=# create table s91("count" int);
CREATE TABLE
Time: 38.981 ms
t=# insert into s91 values (1),(2),(3);
INSERT 0 3
Time: 13.929 ms
t=# select count(base.*) from s91 base;
count
-------
1
2
3
(3 rows)
t=# alter table s91 rename COLUMN a to "manah_manah";
ALTER TABLE
Time: 1.025 ms
t=# select manah_manah(s91.*) from s91;
manah_manah
-------------
1
2
3
(3 rows)
更新:似乎column(alias_name)
是一个有效的语法:
s=# with c(a,b) as (values(1,2),(2,3))
select a(c),(c).a from c;
a | a
---+---
1 | 1
2 | 2
(2 rows)
【讨论】:
感谢您的额外努力!似乎使用对列名的偏好来解析“表达式”。它以某种方式忽略了括号部分,但我还没有在 Postgresql 的gram.y
中找到它
更新示例 - 现在看起来像是一个功能,而不是错误 :)
有趣 :) 我当然可以为我的应用程序切换到 count(1)
。我希望这种行为最终会以某种方式出现在文档中
在语法上这个表达式最接近 function(record)
甚至是转换 typename ( expression )
- 无论如何在文档中找不到类似的东西
IIRC column_names_as_functions 是 QUEL 的遗物,它更接近于关系代数。 (几个月前,pg-hackers 列表上也有一些关于它的模糊信息)以上是关于名称为“count”的计数列返回多行。为啥?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 SQL 计数(*)与 SQL 计数(数字)存在行为差异
使用 CriteriaBuilder 的 JPA 计数(*)。如何使用 CriteriaBuilder 检索 count(*) 列