sql - 在 PostgreSQL 中有没有 WHERE COUNT () 和窗口函数的替代方法?
问题描述
我正在尝试按两列进行分组,并仅按第一列不重复的记录过滤结果。然后,结果值可以分别用作 KEY 和 VALUE。
我以两种不同的方式达到了预期的结果,但似乎都不够。
为了简化问题,我将用一个只有两列和很少值的表来总结它:
create table example (
foreign_key integer,
item_value text
);
insert into example (foreign_key, item_value) values
(1, 'a'), (1, 'a'), (1, 'b'), (1, 'a'), (2, 'a'), (2, 'a'), (2, 'a'),
(3, 'c'), (3, 'a'), (3, 'a'), (4, 'a'), (4, 'c'), (4, 'e'), (5, 'b');
第一种方法是使用 CTE 和WITH
子句,然后在子句中使用子查询进行过滤WHERE
:
with grouped AS (
select foreign_key, item_value
from example
group by 1, 2
order by 1 -- ordering only to view in case of running individually.
)
select *
from grouped g
where (select count(foreign_key) from grouped where foreign_key = g.foreign_key) = 1;
第二种方法是在子句中使用带有OVER
窗口函数的子查询FROM
:
select foreign_key, item_value
from (
select *, count(foreign_key) over(partition by foreign_key) as n
from example
group by 1, 2
) t
where t.n = 1;
两种方式都返回相同的结果,对于所使用的输入是正确的:
foreign_key item_value
2 "a"
5 "b"
但它们似乎过于昂贵,而且阅读起来不那么愉快。
有没有更好的方法来达到相同的结果?
解决方案
通过计算不同的值,这似乎是一个简单的组:
select foreign_key, max(item_value) as item_value
from example
group by foreign_key
having count(distinct item_value) = 1
order by foreign_key;
推荐阅读
- flutter - *为什么* SizedBox 的宽度和高度没有任何影响?
- java - 如何模拟本地 OAuth2RestTemplate restTemplate?
- python - 在 python 子进程中捕获 logger.info 输出?
- mapstruct - 使用 MapStruct 将 JSON 转换为 Java Pojo
- c++ - CGAL 的共享库 (lib[name].so) 可以在没有安装 CGAL 的计算机上使用吗?
- windows - 在 cygwin-gcc 编译程序中未调用 DllMain
- r - 如何仅在一个样本上运行 set.seed() 生成器?
- python - 在 Pandas 中创建具有特定日期的数据框
- node.js - node.js 上的 Sqlite3 产生 SQLITE_ERROR
- javascript - Jquery:使用具有变量名的类附加到 div