sql两张表union all的时候取count,然后进行sum,该怎么实现?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql两张表union all的时候取count,然后进行sum,该怎么实现?相关的知识,希望对你有一定的参考价值。

在最后的地方 随便加个字符, ) a就可以了。缺少一个表名,相当于。

select sum(tmpcount) from ( 
select count(*) as tmpcount from tab1 
union all 
select count(*) as tmpcount from tab2
) a

具体如下:

1、简介

结构化查询语言(Structured Query Language)简称SQL,结构化查询语言是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统;sql 语句就是对数据库进行操作的一种语言。

2、sql语句

更新:update table1 set field1=value1 where 范围

查找:select * from table1 where field1 like '%value1%' (所有包含'value1'这个模式的字符串)

排序:select * from table1 order by field1,field2 [desc]

求和:select sum(field1) as sumvalue from table1

平均:select avg(field1) as avgvalue from table1

最大:select max(field1) as maxvalue from table1

最小:select min(field1) as minvalue from table1[separator]

参考技术A

    oracle 是这样的:

    select sum(tmpcount) from (

    select count(*) as tmpcount from tab1

    union all

    select count(*) as tmpcount from tab2

    )

    结构化查询语言(英文简称:SQL)是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统;同时也是数据库脚本文件的扩展名。

    结构化查询语言是高级的非过程化编程语言,允许用户在高层数据结构上工作。它不要求用户指定对数据的存放方法,也不需要用户了解具体的数据存放方式,所以具有完全不同底层结构的不同 数据库系统,,可以使用相同的结构化查询语言作为数据输入与管理的接口。结构化查询语言语句可以嵌套,这使它具有极大的灵活性和强大的功能。

    UNION于1899年创立於德国的Frondenberg,德国产品向来以精准设计与严谨制程深受世人喜爱,少了绚丽浮夸的外型,简洁的线条呈现的是水准之上的高品质,历经了两次世界大战的“UNION”,百年的时间更加淬砺出它恒久的工艺价值。UNION主要生产车把手、刹车器、曲炳。摩托车用链条、脚踏等。

    Count,计算参数列表中的数字项的个数,是一种电脑计算机内部的数学函数的名字。函数Count在计数时,会把数字、空值、逻辑值、日期或以文字代表的数计算进去。

参考技术B 禁止脱裤子放p,两个傻b

使用 UNION ALL 上一行结果的 SQL 表达式

【中文标题】使用 UNION ALL 上一行结果的 SQL 表达式【英文标题】:SQL Expressions using result of previous row of UNION ALL 【发布时间】:2016-10-01 19:43:51 【问题描述】:

我有这两张表:

Collect: Date, Rute, Value_Collected...
Records: Date, Rute, Value, Type...

在这种情况下,其他列不相关。所以我有这个工作代码:

SELECT
Totals.Date                             AS [Date],
Sum(Totals.Collected)                   AS [Collect],
Sum(Totals.Injected)                    AS [Injections],
Sum(Totals.Spent)                       AS [Expenses],
([Collect] + [Injections]) - [Expenses] AS [Total Day]

FROM (
    SELECT
    Records.Date                        AS [Date],
    0                                   AS [Collected],
    Sum(IIF(Type =  3,Records.Value,0)) AS [Injected],
    Sum(IIF(Type <> 3,Records.Value,0)) AS [Spent]
    FROM Records GROUP BY Records.Date

    UNION ALL

    SELECT
    Collect.Date                 AS [Date],
    Sum(Collect.Value_Collected) AS [Collected],
    0                            AS [Injected],
    0                            AS [Spent]
    FROM Collect GROUP BY Collect.Date
) AS Totals GROUP BY Totals.Date

这给了我这个结果:

|Date       |Collect    |Injections  |Expenses   |Total Day
-----------------------------------------------------------
|5/09/2016  |$47.000   |$0           |$0         |$47.000 |
|6/09/2016  |$20.000   |$0           |$0         |$20.000 |
|7/09/2016  |$13.000   |$0           |$0         |$13.000 |
|11/09/2016 |$122.000  |$0           |$0         |$122.000|
|14/09/2016 |$7.000    |$0           |$0         |$7.000  |
|16/09/2016 |$100.000  |$0           |$7.000     |$93.000 |
|30/09/2016 |$0        |$80.000      |$65.000    |$15.000 |
-----------------------------------------------------------

现在还可以,但是必须像 ([Total Day Of Last Row] + [Collect] + [Injections]) - [Expenses] 而不是 ([Collect] + [Injections]) - [Expenses] 这样计算列 [Total Day] 的公式才能得到这个想要的结果:

|Date       |Collect      |Injections  |Expenses   |Total Day
-------------------------------------------------------------
|5/09/2016  |$47.000      |$0          |$0         |$47.000 |
|6/09/2016  |$20.000      |$0          |$0         |$67.000 |
|7/09/2016  |$13.000      |$0          |$0         |$80.000 |
|11/09/2016 |$122.000     |$0          |$0         |$202.000|
|14/09/2016 |$7.000       |$0          |$0         |$209.000|
|16/09/2016 |$100.000     |$0          |$7.000     |$302.000|
|30/09/2016 |$0           |$80.000     |$65.000    |$317.000|
-------------------------------------------------------------

但我不知道如何获取上一行的[Total Day] 来计算当前行的[Total Day]。如果我尝试在[Totals] 上运行子查询,它会给我一个错误,因为它找不到表Totals。我认为这是因为它不是一个“真正的”表,但我真的不知道如何实现这一点。非常感谢任何帮助。

PS:列和表的名称最初是西班牙文,但翻译目的是为了让您了解我需要完成的工作。

【问题讨论】:

【参考方案1】:

基本上,您需要按累进日期跨字段累积总和,这可以通过相关总和聚合子查询来处理。唯一的挑战是 MS Access 没有像其他 SQL 方言那样的窗口函数来重用派生表查询。所以你需要在子查询中重复联合派生表:

SELECT main.Date, main.Collected AS [Collect], 
       main.Injected As [Injections], main.Spent As [Expenses],
       Ccur((SELECT Sum(sub.Collected) + Sum(sub.Injected) - Sum(sub.Spent) 
             FROM 
               (SELECT Records.Date AS [Date], 0 AS [Collected],
                       Sum(IIF(Type =  3,Records.Value,0)) AS [Injected],
                       Sum(IIF(Type <> 3,Records.Value,0)) AS [Spent]
                FROM Records GROUP BY Records.Date
                UNION ALL
                SELECT Collect.Date AS [Date],
                       Sum(Collect.Value_Collected) AS [Collected],
                       0 AS [Injected],
                       0 AS [Spent]
                FROM Collect GROUP BY Collect.Date
                ) As sub
             WHERE sub.Date <= main.Date)) As [Total Day]

FROM
  (SELECT Records.Date AS [Date], 0 AS [Collected],
          Sum(IIF(Type =  3,Records.Value,0)) AS [Injected],
          Sum(IIF(Type <> 3,Records.Value,0)) AS [Spent]
   FROM Records GROUP BY Records.Date
   UNION ALL
   SELECT Collect.Date AS [Date],
         Sum(Collect.Value_Collected) AS [Collected],
         0 AS [Injected],
         0 AS [Spent]
   FROM Collect GROUP BY Collect.Date
  ) As main

幸运的是,MS Access 确实维护了存储的查询对象,您可以在其中将 UNION 查询保存为单独的查询,并在新查询中引用它以获得更短的脚本:

SELECT main.Date, main.Collected As [Collect], 
       main.Injected As Injections, main.Spent As Expenses,  
       Ccur((SELECT Sum(sub.Collected) + Sum(sub.Injected) - Sum(sub.Spent) 
             FROM RecordsUnionQ As sub
             WHERE sub.Date <= main.Date)) As [Total Day]
FROM RecordsUnionQ As main

使用支持CTE的SQLite 3,您可以使用WITH()子句来保存联合查询,避免在子查询中重复。 CTE 仅在 SQL 语句期间充当临时视图。

WITH main AS
  (SELECT Records.Date AS [Date], 0 AS [Collected],
          Sum(IIF(Type =  3,Records.Value,0)) AS [Injected],
          Sum(IIF(Type <> 3,Records.Value,0)) AS [Spent]
   FROM Records GROUP BY Records.Date
   UNION ALL
   SELECT Collect.Date AS [Date],
         Sum(Collect.Value_Collected) AS [Collected],
         0 AS [Injected],
         0 AS [Spent]
   FROM Collect GROUP BY Collect.Date)

SELECT main.Date, main.Collected AS [Collect], 
       main.Injected As [Injections], main.Spent As [Expenses],
       Ccur((SELECT Sum(sub.Collected) + Sum(sub.Injected) - Sum(sub.Spent) 
             FROM main As sub
             WHERE sub.Date <= main.Date)) As [Total Day]
FROM main;

【讨论】:

非常感谢,您再次救了我的命,您的回答为我解决问题提供了一个很好的方向。我必须重复查询以获取前一天的值并使用它来计算每一行当天的总数,我猜重复查询对性能有非常坏的影响但是......是唯一的方法.. . 我猜 我还有一个小问题,如果这将是 SqLite... 怎么解决?是相同的解决方案吗?或者存在一种更优化的方式来获得相同的结果,我的意思是SELECT (Sum(sub.blah) + Sum(Sub.blah))- Sum(Sub.blah) FROM Totals as Sub WHERE Sub.Date &lt; Totals.Date,而不是重复查询 查看更新 SQLite 示例。效率如何?依靠。视图实际上与 MS Access 中的存储查询相同。 Access 的查询优化器使用存储的查询编译、缓存和查找最佳计划。 非常感谢您的帮助,我一定会更深入地研究WITH()子句,真的很棒。

以上是关于sql两张表union all的时候取count,然后进行sum,该怎么实现?的主要内容,如果未能解决你的问题,请参考以下文章

union和union all的区别

使用 UNION ALL 上一行结果的 SQL 表达式

大厂必考Mysql面试题union all 和 union

oracle中union all

将 UNION ALL 与另一张表一起使用时,保留一张表中的所有记录

mysql合并查询(多张表) union 和 union all