【问题标题】:Sqlite: subtotals in own row aka "rollup"Sqlite:自己行中的小计,又名“汇总”
【发布时间】:2014-03-11 00:50:41
【问题描述】:

我正在寻找一种方法来模拟其他基于 sql 的 dbms 中可用的“汇总”。需要明确的是,我知道如何运行小计,这不是我所追求的。我也知道我可能可以通过编程方式做到这一点。但是,如果可以使用一个(或几个)sql 语句,我宁愿这样做。

例如,对于这样的表:product_type, order_amount, date 我会寻找一份报告,该报告显示按产品类型和日期分组的所有数据,其中一行显示每个产品更改的 order_amount 小计类型和日期。

我只能在 android 上使用 sqlite。我知道足够多的 sql 可能会伤害数据库,但显然不足以模拟汇总,此时我认为这是不可能的。

任何见解(即使“不,它不可能”)表示赞赏。

【问题讨论】:

    标签: android sql sqlite rollup


    【解决方案1】:

    这是一种在 sqlite 下模拟汇总的方法。我偶然发现了 2007 年在数据库 forum 上询问小计和总计的答案。我将在这里用我的简化案例进行总结。

    我有一个表股票,其中包含 Ticker_Symbol(Text)、Underlying(Text) 和 Quantity(Integer) 以及其他字段。对于这个例子,这些就足够了。

    可以使用以下来自 sqlite 的调用来模拟汇总:

    select Ticker_Symbol,Underlying,Quantity from (
    select '1' orderCol, Ticker_Symbol,Underlying,Quantity from stocks 
    union  
    select '2' orderCol, Ticker_Symbol, 'Subtotal' as Underlying, Sum(Quantity) as Quantity from stocks 
    group by Ticker_Symbol 
    union 
    select '99' orderCol, '_' as Ticker_Symbol, 'GrandTotal' as Underlying, sum(Quantity) as Quantity from stocks) 
    as t1  order by case  when orderCol=99 then 1 else 0 end, Ticker_Symbol, orderCol;
    

    这会产生类似于以下的输出:

    |Ticker_Symbol |底层证券|数量| |--------|----------|--------| AAPL AAPL 500 AAPL AAPL 1000 AAPL AAPL 2000 AAPL 小计 3500 AAPL140222P00500000 AAPL 10 AAPL140222P00500000 小计 10 IBM140322C00180000 IBM 25 IBM140322C00180000 小计 25 R140222C00067500 R 10 R140222C00067500 小计 10 VLCCF VLCCF 300 VLCCF VLCCF 2000 VLCCF 小计 2300 _ 总计 5845

    很遗憾,我找不到避免使用 Ticker_Symbol 的方法。理想情况下,最好将当前的 Ticker_Symbol 替换为“Subtotal”(或 GrandTotal),但这不起作用。还要注意使用“_”来确保 GrandTotal 确实出现在最后一行。

    我希望这对其他人有所帮助,如果有人有办法让它变得更好,请添加。

    【讨论】:

      【解决方案2】:

      我自己也遇到了同样的问题 - 在 SQLite3 中模拟 subtotals,这就是我的想法:

      with counter(numm)as(select 1 union all select numm+1 from counter where numm<34),
      str(par,node)as(select 1, numm from counter where numm in(2,5,8,11)union 
      select 11, numm from counter where numm in(12)union 
      select 12, numm from counter where numm in(13,17,20)union 
      select 13, numm from counter where numm in(14,15,16)union 
      select 17, numm from counter where numm in(18,19)union 
      select 2, numm from counter where numm in(3,4)union 
      select 20, numm from counter where numm in(21)union 
      select 21, numm from counter where numm in(22,23)union 
      select 5, numm from counter where numm in(6,7)union 
      select 8, numm from counter where numm in(9,10)union 
      select null, numm from counter where numm in(1)),
      struct(par,node,clevel)as(select par,node,0 from str where par is null union all select c.par,c.node,s.clevel+1 from str c join struct s on s.node=c.par)/*struct*/,
      namez(namee,node)as(select 'Grandtotal', numm from counter where numm in(1)union
      select 'Subtotal1', numm from counter where numm in(2)union
      select 'Subtotal2', numm from counter where numm in(5)union
      select 'Subtotal3', numm from counter where numm in(8)union
      select 'Subtotal4', numm from counter where numm in(11)union
      select 'Subtotal5', numm from counter where numm in(12)union
      select 'Subtotal6', numm from counter where numm in(13)union
      select 'Subtotal7', numm from counter where numm in(17)union
      select 'Subtotal8', numm from counter where numm in(20)union
      select 'Subtotal9', numm from counter where numm in(21)union
      select 'value10', numm from counter where numm in(18)union
      select 'value11', numm from counter where numm in(19)union
      select 'value12', numm from counter where numm in(22)union
      select 'value2', numm from counter where numm in(4)union
      select 'value3', numm from counter where numm in(6)union
      select 'value4', numm from counter where numm in(7)union
      select 'value5', numm from counter where numm in(9)union
      select 'value6', numm from counter where numm in(10)union
      select 'value7', numm from counter where numm in(14)union
      select 'value8', numm from counter where numm in(15)union
      select 'value9', numm from counter where numm in(16)union
      select 'valueN', numm from counter where numm in(23)union
      select 'vaule1', numm from counter where numm in(3)),
      some_random_values(node,val)as(
      select node,
      case node 
        when 3 then 10 when 4 then 33 when 6 then 123 when 7 then 2 
        when 9 then 321 when 10 then 202 when 14 then 2 when 15 then 88 
        when 16 then 56 when 18 then 17 when 19 then 345 when 22 then 99 when 23 then 9 
        else 0 
      end from str),
      sval(par,node,val)as(select s.par,s.node,a.val from str s join some_random_values a on a.node=s.node),
      recur(par,node,val)as(
      select * from sval where par in(select par from str group by par having(node)>1)
      union all
      select b.pAR,b.node,a.val+b.val
      from recur a join sval b on b.node = a.par)
      select s.par,s.node,substr('                            ',1,s.clevel*5)||n.namee name,v.val
      from struct s join namez n on n.node=s.node
      join(select par,node,sum(val)val from recur group by 1,2)v on v.node=s.node
      order by s.node
      

      示例可能看起来有点复杂。主要部分以recur(par,node,val)开头。

      SQLite 3.9.1 上运行良好。

      【讨论】:

        【解决方案3】:

        我参考了 TrustNoOne's Answer 的方法来使用它。

            select securityname,bal,Total from (
        select 1 orderCol,sectorname, '#' || COALESCE (sectorname,'') as securityname ,'' bal ,'' as Total from tablename 
        group by sectorname  --Title
        union 
        select 2 orderCol,sectorname, securityname,bal,'' from tablename --Items
        union  
        select 3 orderCol,sectorname, sectorname || '- Subtotal :' as securityname ,'',Sum(bal) as Total from tablename 
        group by sectorname --SubTotal
        union 
        select 99 orderCol,'_' sectorname, 'Grand Total :' as securityname ,'', sum(bal) as Total from tablename
        group by 1,2,3 --GrandTotal
        ) 
         
        
        Securityname Quantity Total
        #Group1 :
        Item1 50.0
        Item2 30.0
        Group1- Subtotal 80
        #Group2 :
        Item1 10.0
        Group2- Subtotal 10
        Grand Total 90

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-18
          • 1970-01-01
          • 1970-01-01
          • 2015-05-18
          • 2011-12-02
          相关资源
          最近更新 更多