给出下表定义

-- Table: public.my_table

-- DROP TABLE public.my_table;

CREATE TABLE public.my_table
(
    row_id bigint NOT NULL DEFAULT nextval('my_table_id_seq'::regclass),
    user_id text COLLATE pg_catalog."default" NOT NULL,
    item_id text COLLATE pg_catalog."default" NOT NULL,
    my_timestamp timestamp with time zone NOT NULL DEFAULT now(),
    CONSTRAINT my_table_pkey PRIMARY KEY (row_id)
)
WITH (
    OIDS = FALSE
)
TABLESPACE pg_default;

ALTER TABLE public.my_table
    OWNER to my_db;

我试图找出有多少项有多行。
这是我的问题。
select count(k.*) from (select count(item_id), item_id
from my_table as t
group by item_id
having count(item_id) > 1) as k

又回来了
count1 for item1
count2 for item2
....

这不是我想要的
这是另一个问题
select count(*) from (select count(item_id), item_id
from my_table as t
group by item_id
having count(item_id) > 1) as k

我想要什么就要什么
count

我很好奇为什么会有差异,我认为这两个查询是一样的,一个是显式地计算k的结果行,一个是隐式的。
有人能告诉我原因吗?
谢谢

最佳答案

看起来COUNT(record)的行为在不同版本之间是不同的:
数据:

CREATE TABLE my_table
(
    row_id bigint NOT NULL ,
    user_id text COLLATE pg_catalog."default" NOT NULL,
    item_id text COLLATE pg_catalog."default" NOT NULL,
    my_timestamp timestamp with time zone NOT NULL DEFAULT now(),
    CONSTRAINT my_table_pkey PRIMARY KEY (row_id)
);

INSERT INTO my_table VALUES(1,'a','a'),(2,'a','a'),(3,'b','b'),(4,'b','b')
,(5,'c','c'),(6,'c','c'),(7,'c','c'),(8,'d','d'),(9,'d','d');

查询:
select COUNT(k.*)
from (select count(item_id), item_id
      from my_table as t
      group by item_id
      having count(item_id) > 1) as k

-- PostgreSQL 10
-- count
--2
--2
--2
--3

-- PostgreSQL 11
-- count
-- 4

DBFiddle Demo PostgreSQL 10.4
DBFiddle Demo PostgreSQL 11beta2
检查执行计划:
sql - 为什么在通配符中指定子查询的名称会导致在PostgreSQL中查询结果不同?-LMLPHPsql - 为什么在通配符中指定子查询的名称会导致在PostgreSQL中查询结果不同?-LMLPHP
使用http://tatiyants.com/pev/#/plans生成的计划
正如我们在第一个示例中看到的,根本没有第二个聚合。
我将使用simpleEXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON)或将COUNT(*)替换为COUNT(k.*)
select COUNT(*), COUNT(ROW(k.*))
from (select count(item_id), item_id
      from my_table as t
      group by item_id
      having count(item_id) > 1) as k;

-- count count
-- 4     4

DBFiddle Demo

07-26 09:35
查看更多