Sql 对于给定的子组,所有组的总功率是否相等?
我有一个如下的PostgreSQL表:Sql 对于给定的子组,所有组的总功率是否相等?,sql,database,postgresql,aggregate,Sql,Database,Postgresql,Aggregate,我有一个如下的PostgreSQL表: CREATE TABLE foo (man_id, subgroup, power, grp) AS VALUES ( 1, 'Sub_A', 1, 'Group_A' ), ( 2, 'Sub_B', -1, 'Group_A' ), ( 3, 'Sub_A', -1, 'Group_B' ), ( 4, 'Sub_B', 1, 'Group_B' ), ( 5, 'Sub_A', -1, 'Group_A'
CREATE TABLE foo (man_id, subgroup, power, grp)
AS VALUES
( 1, 'Sub_A', 1, 'Group_A' ),
( 2, 'Sub_B', -1, 'Group_A' ),
( 3, 'Sub_A', -1, 'Group_B' ),
( 4, 'Sub_B', 1, 'Group_B' ),
( 5, 'Sub_A', -1, 'Group_A' ),
( 6, 'Sub_B', 1, 'Group_A' ),
( 7, 'Sub_A', -1, 'Group_B' ),
( 8, 'Sub_B', 1, 'Group_B' );
功率计算的工作原理如下:
CREATE TABLE foo (man_id, subgroup, power, grp)
AS VALUES
( 1, 'Sub_A', 1, 'Group_A' ),
( 2, 'Sub_B', -1, 'Group_A' ),
( 3, 'Sub_A', -1, 'Group_B' ),
( 4, 'Sub_B', 1, 'Group_B' ),
( 5, 'Sub_A', -1, 'Group_A' ),
( 6, 'Sub_B', 1, 'Group_A' ),
( 7, 'Sub_A', -1, 'Group_B' ),
( 8, 'Sub_B', 1, 'Group_B' );
grp组A中的子组Sub_A的总功率为(1+(-1))=0grp组A中的子组Sub_B的总功率为(-1)+1)=0
grp组_B中的子组Sub_A的总功率为(-1)+(-1))=-2
grp组_B中的子组Sub_B的总功率为(1+1)=2 因此,组A中Sub_A的功率不等于组B中Sub_A的功率
所以A组中Sub_B的幂不等于B组中Sub_B的幂 我想用
子组
名称查询数据库。如果对于相同的子组
名称幂在所有其他grp
名称中相等,则它将返回True
,否则返回False
例如,sub_A
和sub_B
都将返回False
。推荐的方法是什么
我想要像这样的东西:
SELECT * FROM foo (solution query will be added)
WHERE subgroup = 'sub_A'
它返回
False
假设在CREATE TABLE语句中,“sub_A”表示为“sub_A”(因为Postgres区分大小写),并且您的power
值实际上是整数(如果不是,只需添加强制类型转换;没有它们,下面的代码更简单),然后,您可以按如下方式计算组中每个子组的功率:
select
subgroup,
grp,
sum(power) as sum_power
from
foo
group by
subgroup,
grp
select
subgroup
from (
select
subgroup,
grp,
sum(power) as sum_power
from
foo
group by
subgroup,
grp
) as subpwr
group by
subgroup
having
min(sum_power) = max(sum_power);
要确定子组的所有总功率值是否相同,只需检查最小值和最大值是否相同。将上一个查询转换为子查询,其中主查询执行该比较,如下所示:
select
subgroup,
grp,
sum(power) as sum_power
from
foo
group by
subgroup,
grp
select
subgroup
from (
select
subgroup,
grp,
sum(power) as sum_power
from
foo
group by
subgroup,
grp
) as subpwr
group by
subgroup
having
min(sum_power) = max(sum_power);
仔细阅读问题
我想用子组名称查询数据库
以及:
我想要像这样的东西
SELECT * FROM foo (solution query will be added)
WHERE subgroup = 'Sub_A'
性能的重要一点是尽早排除不相关的行,只计算给定子组的聚合。然后(假设不止几个不同的子组),(子组)
上的索引可以帮助:
CREATE INDEX ON foo (subgroup);
如果给定子组中至少有两个组的总和不同,则以下每个查询都返回FALSE
,在所有其他情况下返回TRUE
(查询5的一个小例外,见下文)
问题1
问题2
问题3
问题4
这个很特别。相关答案及解释:
NULL
值,则最后一个可能会失败。(但无论如何,在这种情况下,您必须定义预期结果。)
我运行了一个扩展测试,发现所有查询在理想条件下的执行情况大致相同:
dbfiddle
问题5往往比其他问题快一点。这里有一个其他答案还没有提到的方法
SELECT SUM(power) = FIRST_VALUE(SUM(power)) OVER () powpow
FROM foo
WHERE subgroup = 'Sub_A'
GROUP BY grp
ORDER BY powpow
LIMIT 1
-- returns:
-- false if some values differ
-- true if all values are the same
-- no rows if the where condition fails to match any rows.
请不要交叉发帖。我随意修改了一些与问题(或者我认为是这样)正交的、让人分心的拼写错误。请始终披露您的Postgres版本。大致有多少行、不同的组和子组?基数和值频率可能与选择最佳查询相关。如果子组
Sub_A
根本不存在,或者只存在一个组,您希望得到什么结果。我觉得选择不明确,因为人们可能希望NULL
,FALSE
或TRUE
一如既往,您的答案是说明性的。我想知道您是否可以将我的解决方案与您测试过的5个备选方案进行比较。我很好奇,在这种设置下,避免子查询而使用窗口表达式和排序对性能有什么影响。@Haleemuli:我在测试电池中添加了:works,性能与其余的:dbfiddle差不多
SELECT min(total_power) = max(total_power) -- can fail for NULL values
FROM (
SELECT sum(power) AS total_power
FROM foo
WHERE subgroup = 'Sub_A'
GROUP BY grp
) sub;
SELECT SUM(power) = FIRST_VALUE(SUM(power)) OVER () powpow
FROM foo
WHERE subgroup = 'Sub_A'
GROUP BY grp
ORDER BY powpow
LIMIT 1
-- returns:
-- false if some values differ
-- true if all values are the same
-- no rows if the where condition fails to match any rows.