簡體   English   中英

SQL子查詢按列值獲取行

[英]SQL subquery to fetch rows by column values

我有這樣的PostgreSQL表:

CREATE TABLE foo(man_id, subgroup, power, grp)
AS VALUES
    (1, 'Sub_A',  4, 'Group_A'),
    (2, 'Sub_B', -1, 'Group_A'),
    (3, 'Sub_A', -1, 'Group_B'),
    (4, 'Sub_B',  6, 'Group_B'),
    (5, 'Sub_A',  5, 'Group_A'),
    (6, 'Sub_B',  1, 'Group_A'),
    (7, 'Sub_A', -1, 'Group_B'),
    (8, 'Sub_B',  2, 'Group_B'),
    (9, 'Sub_C',  2, 'Group_B');

功率計算如下:

  • grp Group_A中的Subgroup Sub_A的總功率為(4 + 5)= 9
  • grp Group_A中子組Sub_B的總功率為((-1)+ 1)= 0
  • grp Group_B中的Subgroup Sub_A的總功率為((-1)+(-1))= -2
  • grp Group_B中子組Sub_B的總功率為(6 + 2)= 8

因此,Group_A中Sub_A的功率不等於Group_B中Sub_A的功率

因此,Group_A中Sub_B的冪不等於Group_B中Sub_B的冪

我想查詢數據庫並獲取行,對於相同的subgroup名稱,所有其他grp名稱的總power不相等。

推薦的方法是什么?

我可以找到總功率的總和:

SELECT sum(power) AS total_power
FROM   foo
GROUP  BY grp

MySQL解決方案也將被接受。

單程:

SELECT f.*
FROM  (
   SELECT subgroup
   FROM  (
      SELECT subgroup, grp, sum(power) AS total_power
      FROM   foo
      GROUP  BY subgroup, grp
      ) sub
   GROUP  BY 1
   HAVING min(total_power) <> max(total_power)  -- can fail for NULL values;
   ) sg
JOIN foo f USING (subgroup);

在您的示例中,除最后一行帶有“ Sub_C”外,所有行均符合條件。

與您之前的問題密切相關:

類似的解釋和注意事項。

db <> 在這里撥弄

我認為解決您的問題的一種方法是,您希望合計一組中子組的力量,然后查找具有相同名稱的子組是否存在於另一組具有不同功效的組中。

第一步是合計所需的力量:

SELECT grp, subgroup, sum(power) as power
FROM foo
GROUP BY grp, subgroup

那應該給你這樣的結果:

grp      subgroup  power
-------  --------  -----
Group_A  Sub_A      9
Group_A  Sub_B      0
Group_B  Sub_A     -2
Group_B  Sub_B      8
Group_B  Sub_C      2

有了這些信息后,您就可以使用CTE將結果與自身連接起來,進行比較以獲得所需的結果。 您無需指定是否要顯示Sub_C ,如果“不存在”被視為具有“不同的總能力”,那么您將需要使用左聯接並檢查別名b空值。 連接中的<使得它使得每個差異僅在低階組為grp1時出現一次。

WITH totals AS (
    SELECT grp, subgroup, sum(power) as power
    FROM foo
    GROUP BY grp, subgroup
    ORDER BY grp, subgroup
)
SELECT a.subgroup,
       a.grp as grp1, a.power as Power1,
       b.grp as grp2, b.power as Power2
FROM totals a
    INNER JOIN totals b ON b.subgroup = a.subgroup
                           and a.grp < b.grp
WHERE b.power <> a.power
ORDER BY a.subgroup, a.grp, b.grp 
with totals as (
    select grp, subgroup, sum(power) as total_power
    from foo
    group by grp, subgroup
)
select * from totals t1
where t1.total_power <> all (
    select t2.total_power from totals t2
    where t2.subgroup = t.subgroup and t2.grp <> t1.grp
)

要么

with totals as (
    select grp, subgroup, sum(power) as total_power
    from foo
    group by grp, subgroup
), matches as (
    select grp, subgroup, count(*) over (partition by subgroup, total_power) as matches
)
select * from counts where matches = 1;

我將使用窗口函數:

select f.*
from (select f.*,
             min(sum_value)) over (partition by group) as min_sum_value,
             max(sum_value)) over (partition by group) as max_sum_value,
      from (select f.*,
                   sum(value) over (partition by subgroup, group) as sum_value
            from foo f
           ) f
      ) f
where min_sum_value <> max_sum_value;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM