【问题标题】:Summary and Total Invoice Data in SQL QuerySQL 查询中的汇总和总发票数据
【发布时间】:2016-02-23 17:06:19
【问题描述】:

我需要一个可以放入报表显示工具(如 Crystal Reports 或 Report Writer)的完整查询。

我几乎完成了这项工作,但我似乎无法获得底部的 Grand Totals 行。

SQL Fiddle 不会建这个表,说内存不足。 (???) 所以,我能做的就是把它贴在这里。

这是我的示例表:

CREATE TABLE [dbo].[jp2Invoice](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [InvoiceNumber] [varchar](20) NOT NULL,
    [Subtotal] [decimal](9, 4) NOT NULL,
    [Taxable] [varchar](1) NULL,
    [TaxRate] [decimal](9, 4) NULL,
    [TaxableAmount] [decimal](9, 4) NOT NULL,
    [NontaxableAmount] [decimal](9, 4) NOT NULL,
    [Tax] [decimal](9, 4) NOT NULL,
    [Total] [decimal](9, 4) NOT NULL,
    [AmountTendered] [decimal](9, 4) NOT NULL,
    [ChangeAmount] [decimal](9, 4) NOT NULL,
    [AmountDue] [decimal](9, 4) NOT NULL,
    [ChargeAmount] [decimal](9, 4) NOT NULL,
 CONSTRAINT [PK_jp2Invoice] PRIMARY KEY CLUSTERED ([Id] ASC) ON [PRIMARY]
) ON [PRIMARY]

下面是一些示例数据:

insert into jp2Invoice(
  InvoiceNumber, Subtotal, Taxable, TaxRate, TaxableAmount, NontaxableAmount, Tax, Total, AmountTendered, ChangeAmount, AmountDue, ChargeAmount
) values 
('ABC001',  19.9500, 'Y', 8.2500,  19.9500,   0.0000,  1.6458,  21.5958,  40.0000, 18.4041,   0.0000,   0.0000),
('ABC002', 558.8300, 'Y', 6.0000, 335.3000, 223.5300, 20.1180, 355.4180,   0.0000,  0.0000,   0.0000, 355.4180),
('ABC003', 281.4700, 'Y', 8.2500, 281.4700,   0.0000, 23.2212, 304.6912,   0.0000,  0.0000,   0.0000, 304.6913),
('ABC004',  95.9800, 'Y', 8.2500,  95.9800,   0.0000,  7.9183, 103.8983,   0.0000,  0.0000,   0.0000, 103.8983),
('ABC005',  73.1900, 'Y', 8.2500,  73.1900,   0.0000,  6.0381,  79.2281, 100.0000, 20.7718,   0.0000,   0.0000),
('ABC006', 215.6500, 'N', 0.0000,   0.0000, 215.6500,  0.0000, 215.6500,   0.0000,  0.0000,   0.0000, 215.6500),
('ABC007', 146.0200, 'Y', 8.2500, 146.0200,   0.0000, 12.0466, 158.0666,   0.0000,  0.0000,   0.0000, 158.0667);

有了这些数据,我创建了这个查询:

select
 case when ChargeAmount=0 then 'Cash' else 'Charge' end as 'TxType',
 TaxRate,
 sum(Subtotal) as 'SubTotal',
 sum(TaxableAmount) as 'TaxAmt',
 sum(AmountTendered) as 'Tendered',
 sum(ChangeAmount) as 'Change',
 sum(ChargeAmount) as 'Charged',
 sum(Total) as 'Total'
from jp2Invoice
group by case when ChargeAmount=0 then 'Cash' else 'Charge' end,
 TaxRate

该查询生成下表:

TxType TaxRate  SubTotal      TaxAmt    Tendered     Change  Charged    Total
Charge  0.0000  215.6500      0.0000      0.0000     0.0000 215.6500    215.6500
Charge  6.0000  558.8300    335.3000      0.0000     0.0000 355.4180    355.4180
Cash    8.2500   93.1400     93.1400    140.0000    39.1759   0.0000    100.8239
Charge  8.2500  523.4700    523.4700      0.0000     0.0000 566.6563    566.6561

First:看起来该表首先按 TaxRate 分组,然后按“TxType”分组,尽管 group by 子句显示“TxType”计算首先出现。如何强制“现金”在前,“费用”在后?

第二:我如何在底部写一个 Grand Total 行,计算显示总数?我在下面的示例表中手工计算了一个:

TxType TaxRate  SubTotal      TaxAmt    Tendered     Change  Charged    Total
Charge  0.0000  215.6500      0.0000      0.0000     0.0000  215.6500    215.6500
Charge  6.0000  558.8300    335.3000      0.0000     0.0000  355.4180    355.4180
Cash    8.2500   93.1400     93.1400    140.0000    39.1759    0.0000    100.8239
Charge  8.2500  523.4700    523.4700      0.0000     0.0000  566.6563    566.6561
Totals         1391.0900    951.91      140.0000    39.1759 1137.7243   1238.5480

其中可能有一些拼写错误,因为它都是手工编辑的。

如何让数据首先按 TxType 显示并在底部显示总计行?

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    在 SQL Server 中,您可以使用 WITH ROLLUP 获取总计行并使用 ORDER BY 对行进行排序。您还可以使用 GROUPING() 添加“TOTALS”标签。

    select
     CASE WHEN GROUPING(case when ChargeAmount=0 then 'Cash' else 'Charge' end) = 1 THEN 'Total' ELSE case when ChargeAmount=0 then 'Cash' else 'Charge' end END as 'TxType',
     TaxRate,
     sum(Subtotal) as 'SubTotal',
     sum(TaxableAmount) as 'TaxAmt',
     sum(AmountTendered) as 'Tendered',
     sum(ChangeAmount) as 'Change',
     sum(ChargeAmount) as 'Charged',
     sum(Total) as 'Total'
    from jp2Invoice
    group by case when ChargeAmount=0 then 'Cash' else 'Charge' end,
     TaxRate WITH ROLLUP
    
    ORDER BY case when ChargeAmount=0 then 'Cash' else 'Charge' end
    

    【讨论】:

    • Union ALL更好的答案
    • 这也会为 TxTyp 添加小计。您可以避免使用:HAVING GROUPING(case when ChargeAmount=0 then 'Cash' else 'Charge' end) = GROUPING(TaxRate),然后添加到ORDER BY 以确保总数在结果末尾。可能有比比较GROUPING 值更优雅的方法,但我没有立即想到。
    • 您也可以使用 CTE 从上面的查询中获取结果,然后将 NULL 值设为 ISNULL 以使其为空。
    【解决方案2】:

    使用UNION ALL

    select
     case when ChargeAmount=0 then 'Cash' else 'Charge' end as 'TxType',
     TaxRate,
     sum(Subtotal) as 'SubTotal',
     sum(TaxableAmount) as 'TaxAmt',
     sum(AmountTendered) as 'Tendered',
     sum(ChangeAmount) as 'Change',
     sum(ChargeAmount) as 'Charged',
     sum(Total) as 'Total'
    from jp2Invoice
    group by case when ChargeAmount=0 then 'Cash' else 'Charge' end, TaxRate
    UNION ALL
    select
    'Totals',
    NULL,
    sum(Subtotal) as 'SubTotal',
    sum(TaxableAmount) as 'TaxAmt',
    sum(AmountTendered) as 'Tendered',
    sum(ChangeAmount) as 'Change',
    sum(ChargeAmount) as 'Charged',
    sum(Total) as 'Total'
    from jp2Invoice
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-24
      • 2013-12-20
      • 1970-01-01
      • 2010-10-11
      • 2021-11-16
      • 2020-03-07
      相关资源
      最近更新 更多