【问题标题】:Can I join two Select sum SQL queries from the same table but with different filters?我可以加入来自同一个表但使用不同过滤器的两个 Select sum SQL 查询吗?
【发布时间】:2020-12-18 05:58:40
【问题描述】:

我遇到了一个问题,我试图将来自同一个表但条件不同的两个 SELECT 和添加到一个结果中。

代码如下:

DROP TABLE Match CASCADE CONSTRAINTS;

CREATE TABLE Match 
(
    Heim VARCHAR(50),
    Gast VARCHAR(50),
    HeimP NUMBER,
    GastP NUMBER
);

INSERT INTO Match 
VALUES ('Bayern München', 'Borussia Dortmund', 1, 1);

INSERT INTO Match 
VALUES ('Borussia Dortmund', 'Bayern München', 0, 3);
INSERT INTO Match 
VALUES ('Bayern München', 'Schalke', 3, 0);
INSERT INTO Match 
VALUES ('Schalke', 'Bayern München', 0, 3);

COMMIT;


SELECT SUM(HeimP) AS Heimpoints 
FROM Match 
WHERE Heim = 'Bayern München';

SELECT SUM(GastP) AS Gastpoints 
FROM Match 
WHERE Gast = 'Bayern München';

【问题讨论】:

  • 您的 RDBMS 和版本?我们可以假设'Bayern München' 永远不会同时是Heim Gast? (是否有 CHECK 约束来确定?)
  • 这是一个测试数据库,仅用于教育目的。但是,是的,我应该内置约束。感谢您的提示和您的时间:)

标签: sql oracle select sum


【解决方案1】:

一种方法是将where 子句中的条件替换为case 表达式中的条件,并仅对相关行求和:

SELECT SUM(CASE heim WHEN 'Bayern München' THEN heimp END) AS Heimpoints,
       SUM(CASE gast WHEN 'Bayern München' THEN gastp END) AS Gastpoints
FROM   match
WHERE  'Bayern München' IN (heim, gast) -- optimization to not query useless rows

【讨论】:

    【解决方案2】:

    您可以在SUM() 中使用CASE 表达式:

    SELECT SUM(
             CASE 'Bayern München'
               WHEN Heim THEN HeimP 
               WHEN Gast THEN GastP
             END
           ) AS points 
    FROM Match 
    WHERE 'Bayern München' IN (Gast, Heim);
    

    请参阅demo
    结果:

    > | POINTS |
    > | -----: |
    > |     10 |
    

    【讨论】:

      【解决方案3】:

      NUMBER 让我觉得你在使用 Oracle。那是一个支持横向连接的数据库(这是标准 SQL,但并非所有数据库都支持)。

      这样的可能是最简单的解决方案:

      select sum(x.points)
      from match m cross join lateral
           (select m.heimp as team, m.heimp as points from dual union all
            select m.gast, m.gastp from dual
           ) x
      where x.team = 'Bayern München';
      

      与仅提及特定团队一次的其他解决方案相比,这具有优势(因此避免了拼写错误)。也许更重要的是,它很容易概括 致所有团队:

      select x.team sum(x.points)
      from match m cross join lateral
           (select m.heimp as team, m.heimp as points from dual union all
            select m.gast, m.gastp from dual
           ) x
      group by x.team;
      

      在不支持横向连接的数据库中,您可以使用union all 执行类似的操作。

      【讨论】:

      • 连接怎么能比简单的表扫描更简单?
      • 没错,我正在使用 SQL Developer。抱歉,我在最初的问题中忘记了。是的,这也适用于我。我正在尝试理解 SQL,所以感谢您的建议。
      • @ChristopherWilger 。 . . SQL Developer 确实与此无关。 Oracle 支持横向连接。 Forpas 不理解它们,所以请忽略该评论。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多