如何在SELECT中获取每行的SUM值而不使用表中的两次并且不使用'WITH'子句?

时间:2018-03-23 19:00:00

标签: android sqlite android-sqlite

我需要获取查询中每行的总SUM,但我不想在表中输入两次。

我试过这样做:

SELECT id, value, SUM(value) as total FROM product

但我的结果是:

id  value  total
3    30     60

如果我执行下面的查询,我会得到我想要的结果,但我需要在表中进行两次:

SELECT id, value, (SELECT SUM(value) FROM product) as total FROM product

或者如果我使用'WITH'子句,但在Android 5之前不支持:

WITH data AS (SELECT id, value FROM product) 
    SELECT id, value, (SELECT SUM(value) FROM data) as total FROM data

通缉结果:

id  value  total
1    10     60
2    20     60
3    30     60

谢谢!

2 个答案:

答案 0 :(得分:1)

使用您的SQLite版本是不可能的。你必须使用两个选择。

答案 1 :(得分:0)

基本上你必须使用子查询。

然而,也许您可​​能不太关心第二个表,因为我相信查询计划程序将确定它只需要计算一次总和并且不需要变量,因为它将值存储在缓存中。

我认为使用EXPLAIN QUERY PLAN your_query的结果显示了这一点。即使用

EXPLAIN QUERY PLAN SELECT id, value, (SELECT sum(value) FROM products) AS total FROM products;

导致: -

enter image description here

这被解释为( 参见粗体陈述 ): -

  

1.3。子查询

     

在上面的所有例子中,第一列(列" selectid")是   始终设置为0.如果查询包含子选择,则作为其中一部分   FROM子句或作为SQL表达式的一部分,然后输出   EXPLAIN QUERY PLAN还包含每个子选择的报告。每   子选择被分配了一个独特的,非零的选择"值。该   顶级SELECT语句始终为selectid值0指定。   例如:

sqlite> EXPLAIN QUERY PLAN SELECT (SELECT b FROM t1 WHERE a=0), (SELECT a FROM t1 WHERE b=t2.c) FROM t2;
0|0|0|SCAN TABLE t2
0|0|0|EXECUTE SCALAR SUBQUERY 1
1|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)
0|0|0|EXECUTE CORRELATED SCALAR SUBQUERY 2
2|0|0|SEARCH TABLE t1 USING INDEX i3 (b=?)
     

上面的示例包含一对分配的标量子查询   selectid值1和2.除SCAN记录外,还有2个   " EXECUTE"与顶级子查询关联的记录(selectid 0),   指示子查询1和2由顶级查询执行   在标量上下文中。 EXECUTE中存在CORRELATED限定符   与标量子查询2关联的记录表示查询必须   为顶级查询访问的每一行单独运行。的及其   与子查询1相关的记录中的缺失意味着   子查询只运行一次,结果缓存。换句话说,   子查询2可能更具性能关键,因为它可能运行很多   次,而子查询1只运行一次

     

除非应用展平优化,否则将显示子查询   在SELECT语句的FROM子句中,SQLite执行子查询   并将结果存储在临时表中。然后它使用内容   临时表的名称,代替子查询来执行父项   查询。这在EXPLAIN QUERY PLAN的输出中显示   替换" SCAN SUBQUERY"记录" SCAN TABLE"记录下来   通常出现在FROM子句中的每个元素。例如:

sqlite> EXPLAIN QUERY PLAN SELECT count(*) FROM (SELECT max(b) AS x FROM t1 GROUP BY a) GROUP BY x;
1|0|0|SCAN TABLE t1 USING COVERING INDEX i2
0|0|0|SCAN SUBQUERY 1
0|0|0|USE TEMP B-TREE FOR GROUP BY
     

如果在FROM中的子查询上使用展平优化   SELECT语句的子句,然后是EXPLAIN QUERY PLAN的输出   反映了这一点例如,在下面没有" SCAN   SUBQUERY"即使在FROM子句中有子查询,也会记录   顶级SELECT。相反,由于展平优化确实如此   在这种情况下适用,EXPLAIN QUERY PLAN报告显示顶部   使用表t1和的嵌套循环连接实现级别查询   T2。

sqlite> EXPLAIN QUERY PLAN SELECT * FROM (SELECT * FROM t2 WHERE c=1), t1;
0|0|0|SEARCH TABLE t2 USING INDEX i4 (c=?)
0|1|1|SCAN TABLE t1

EXPLAIN QUERY PLAN

结束注释

这句话或许与此相关: -

  

SQL的最佳功能(在其所有实现中,而不仅仅是SQLite)   是它是一种声明性语言,而不是一种程序性语言。什么时候   在SQL中编程,你告诉系统你想要计算什么,而不是   如何计算它。确定如何委派的任务   SQL数据库引擎中的查询计划子系统。

Query Planning

您可能还会发现感兴趣的he SQLite Query Optimizer Overview,并指出自版本3.8.0 The Next-Generation Query Planner开始使用。