Sqlite:在自己的行中称为“汇总”的小计

时间:2014-02-12 15:32:18

标签: android sql sqlite rollup

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

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

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

任何见解(即使'不可能')都表示赞赏。

3 个答案:

答案 0 :(得分:1)

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

我有一个表库存,其中包含Ticker_Symbol(文本),底层(文本)和数量(整数)等字段。这些就足够了。

可以使用sqlite的以下调用来模拟Rollup:

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      |Underlying|Quantity|
|-------------------|----------|--------|
AAPL                 AAPL         500
AAPL                 AAPL        1000
AAPL                 AAPL        2000
AAPL                 Subtotal    3500
AAPL140222P00500000  AAPL          10
AAPL140222P00500000  Subtotal      10
IBM140322C00180000   IBM           25
IBM140322C00180000   Subtotal      25
R140222C00067500     R             10
R140222C00067500     Subtotal      10
VLCCF                VLCCF        300
VLCCF                VLCCF       2000
VLCCF                Subtotal    2300
_                    GrandTotal  5845

不幸的是,我找不到避免使用Ticker_Symbol的方法。理想情况下,用“Subtotal”(或GrandTotal)替换当前的Ticker_Symbol会很不错,但这不行。另请注意使用“_”确保GrandTotal确实显示在最后一行。

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

答案 1 :(得分:0)

我自己遇到了同样的问题-在subtotals中模拟SQLite3,在这里,我得出以下结论:

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上运行良好。

答案 2 :(得分:0)

我参考 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
) 
 
<头>
安全名称 数量 总计
#Group1 :
项目 1 50.0
Item2 30.0
Group1- 小计 80
#Group2 :
项目 1 10.0
Group2- 小计 10
总计 90