代码之家  ›  专栏  ›  技术社区  ›  Regressor

在SQL中获取类别百分比的最有效方法是什么

sql
  •  0
  • Regressor  · 技术社区  · 5 年前

    假设我有一张这样的桌子-

    with temp as 
    (
    select "a" as product, 100 as sales union all
    select "b" as product, 200 as sales union all
    select "c" as product, 300 as sales 
    
    )
    

    -- Query 1
    with temp as 
    (
    select "a" as product, 100 as sales union all
    select "b" as product, 200 as sales union all
    select "c" as product, 300 as sales 
    
    )
    
    select *,
    sales * 100 / sum(sales) over ()  as percentage_sales
    from temp t
    

    或者

    -- Query 2
    with temp as 
    
    (
    select "a" as product, 100 as sales union all
    select "b" as product, 200 as sales union all
    select "c" as product, 300 as sales 
    
    )
    
    , total as 
    (
    select sum(sales) grand_total from temp 
    )
    
    select product, sales, 
    sales * 100 / t.grand_total as percentage_sales
    from temp, total t
    

    哪一个查询更高效和优化?它是基于我们使用的SQL引擎吗?或者这里有一个总的经验法则吗?

    我试图从一般的角度来理解它,而不是从任何DBMS供应商的角度来理解它。

    1 回复  |  直到 5 年前
        1
  •  0
  •   The Impaler    5 年前

    这些功能与重新表述查询(重写等效查询)、添加优化、生成多个查询计划以及正确评估每个查询计划的成本的能力有关。

    此外,上述内容还受到引擎中可用数据库操作的影响。与强大的引擎(Oracle、DB2)相比,更简单的引擎(如MySQL)有更少的操作可供选择。

    对于某些引擎,这两个查询实际上是等价的。重写阶段(解析后的ritgh)可能会决定以另一种方式重写它,因为那样会产生相同的结果。记住这是完全正确的,因为SQL是 语言,不是 命令 一个。

    所以,底线是:这在很大程度上取决于数据库。为什么不在你选择的数据库中检索每一个的执行计划呢?这会告诉你一些事情。另外,在这个过程中你会学到很多。

        2
  •  0
  •   Gordon Linoff    5 年前

    pivot ,但这不是跨数据库进行比较的标准功能。)

    您的示例特别简单,因此这两种方法可能非常接近。如果你有一个 partition by join ,那么除了最小的数据集之外,它很可能是任何东西。

    我确实同意比较者的观点,对于这样的问题,你应该测试你的数据库和数据。但是我希望窗口函数通常会直接获胜,可能是平手,因为您的示例是一个非常简单的用例。