小计和总计列

发布于 2024-09-01 03:27:45 字数 1946 浏览 15 评论 0原文

在 Visual Foxpro 9 中,我尝试编写带有产品“小计”列和报告“总计”列的 sql。
有效的 sql 代码如下,但是当我插入注释掉的“Case”代码时,我收到的错误似乎随着我更正前面的错误而增加。
谁能告诉我应该在哪里插入“case”以及代码有什么问题吗?

SELECT qItemSaleLines.ItemID, ;
qItems.ItemID, ;
qItemSaleLines.SaleID, ;
qSales.SaleID, ;
qSales.CardRecordID, ;
qCustomers.CardRecordID, ;
qItems.ItemNumber AS ProdCODE, ;
qItems.ItemName AS StkNAME, ;
qCustomers.LastName AS CUSTOMER, ;
qSales.InvoiceNumber AS SaleINVNo,  ;
qSales.InvoiceDate AS SaleDATE, ;
qItemSaleLines.Quantity AS SaleQTY, ;
qItemSaleLines.TaxExclusiveTotal AS SALE, ;
qItemSaleLines.CostOfGoodsSoldAmount AS COGS, ; 
qItemSaleLines.TaxExclusiveTotal - qItemSaleLines.CostOfGoodsSoldAmount AS MARGIN, ;
(qItemSaleLines.TaxExclusiveTotal - qItemSaleLines.CostOfGoodsSoldAmount) *  /        qItemSaleLines.TaxExclusiveTotal AS MPERCENT ;
FROM qItemSaleLines, qItems, qSales, qCustomers ; 
WHERE qSales.CardRecordID = qCustomers.CardRecordID AND qItemSaleLines.SaleID =    qSales.SaleID AND ;
qItemSaleLines.ItemID = qItems.ItemID AND qSales.InvoiceDate > {^2009-06-30} ;
ORDER BY qItems.ItemNumber, qSales.InvoiceDate ;


*!* (SELECT qItems.ItemID, qItemSaleLines.ItemID, qItemSaleLines.TaxExclusiveTotal, ; 
*!*         CASE WHEN qItems.ItemID = (SELECT TOP 1 qItems.ItemID FROM   qItems.ItemID, ;
*!*             WHERE qItems.ItemID = qItemSaleLines.ItemID, ;
*!*             ORDER BY qItems.ItemID desc), ;
*!*         THEN (SELECT SUM(qItemSaleLines.TaxExclusiveTotal) FROM qItemSaleLines.TaxExclusiveTotal,; 
*!*             WHERE qItems.ItemID <= qItemSaleLines.ItemID AND qItems.ItemID = qItemSaleLines.ItemID, ; 
*!*         ELSE ' ' END AS 'PROD-SALE'), ;
*!*     CASE WHEN qItems.ItemID = (SELECT TOP 1 qItems.ItemID FROM qItems.ItemID, ; 
*!*             ORDER BY qItems.ItemID desc), ;
*!*     THEN (SELECT SUM(qItemSaleLines.TaxExclusiveTotal) FROM qItemSaleLines.TaxExclusiveTotal, ;
*!*         ELSE ' ' END AS 'Grand Total') ;

In Visual Foxpro 9 I am trying to write an sql with a product "subtotal" column and a report "total" column.
The sql code that works is as follows, but when I insert the commented out "Case" code I get errors that seem to increase as I correct the preceeding error.
Can any one tell me in which place I should insert the "case" and what is wrong with the code?

SELECT qItemSaleLines.ItemID, ;
qItems.ItemID, ;
qItemSaleLines.SaleID, ;
qSales.SaleID, ;
qSales.CardRecordID, ;
qCustomers.CardRecordID, ;
qItems.ItemNumber AS ProdCODE, ;
qItems.ItemName AS StkNAME, ;
qCustomers.LastName AS CUSTOMER, ;
qSales.InvoiceNumber AS SaleINVNo,  ;
qSales.InvoiceDate AS SaleDATE, ;
qItemSaleLines.Quantity AS SaleQTY, ;
qItemSaleLines.TaxExclusiveTotal AS SALE, ;
qItemSaleLines.CostOfGoodsSoldAmount AS COGS, ; 
qItemSaleLines.TaxExclusiveTotal - qItemSaleLines.CostOfGoodsSoldAmount AS MARGIN, ;
(qItemSaleLines.TaxExclusiveTotal - qItemSaleLines.CostOfGoodsSoldAmount) *  /        qItemSaleLines.TaxExclusiveTotal AS MPERCENT ;
FROM qItemSaleLines, qItems, qSales, qCustomers ; 
WHERE qSales.CardRecordID = qCustomers.CardRecordID AND qItemSaleLines.SaleID =    qSales.SaleID AND ;
qItemSaleLines.ItemID = qItems.ItemID AND qSales.InvoiceDate > {^2009-06-30} ;
ORDER BY qItems.ItemNumber, qSales.InvoiceDate ;


*!* (SELECT qItems.ItemID, qItemSaleLines.ItemID, qItemSaleLines.TaxExclusiveTotal, ; 
*!*         CASE WHEN qItems.ItemID = (SELECT TOP 1 qItems.ItemID FROM   qItems.ItemID, ;
*!*             WHERE qItems.ItemID = qItemSaleLines.ItemID, ;
*!*             ORDER BY qItems.ItemID desc), ;
*!*         THEN (SELECT SUM(qItemSaleLines.TaxExclusiveTotal) FROM qItemSaleLines.TaxExclusiveTotal,; 
*!*             WHERE qItems.ItemID <= qItemSaleLines.ItemID AND qItems.ItemID = qItemSaleLines.ItemID, ; 
*!*         ELSE ' ' END AS 'PROD-SALE'), ;
*!*     CASE WHEN qItems.ItemID = (SELECT TOP 1 qItems.ItemID FROM qItems.ItemID, ; 
*!*             ORDER BY qItems.ItemID desc), ;
*!*     THEN (SELECT SUM(qItemSaleLines.TaxExclusiveTotal) FROM qItemSaleLines.TaxExclusiveTotal, ;
*!*         ELSE ' ' END AS 'Grand Total') ;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

口干舌燥 2024-09-08 03:27:45

此外,如果您只想将总计作为表中的列,则可以执行类似的操作,

select ;
       Tbl.YourColumns,;
       PerItem.TotalPerItem,;
       RptTotal.TotalPerAll;
   from ;
       YourOtherTables Tbl,;
       ( select YourSalesTable.ItemID,;
                sum( CalculatedSales ) as TotalPerItem;
             From;
                YourSalesTable;
             Group by ;
                ItemID ) PerItem,;
       ( select sum( CalculatedSales ) as TotalPerAll;
             From ;
                YourTalesTable ) RptTotal;
   where ;
       YourOtherJoinConditions;
      AND YourOtherTables.ItemID = PerItem.ItemID;
   order by ;
       whatever;
   into ;
       cursor YourReportResults

因为最后 2 个表(按 itemID 分组)将创建每个项目的总计。通过将最终的 where 仅连接到别名 PerItem 的 ItemID,您将获得该列的总数。但是,由于别名 RptTotal 上没有连接,您将得到笛卡尔连接...但由于它始终有 1 条记录,因此每行将具有与其“TotalPerAll”列相同的值。

我希望这两个解决方案能够满足您的需求。

Additionally, if you do just want the totals as columns in the table, you could do something like

select ;
       Tbl.YourColumns,;
       PerItem.TotalPerItem,;
       RptTotal.TotalPerAll;
   from ;
       YourOtherTables Tbl,;
       ( select YourSalesTable.ItemID,;
                sum( CalculatedSales ) as TotalPerItem;
             From;
                YourSalesTable;
             Group by ;
                ItemID ) PerItem,;
       ( select sum( CalculatedSales ) as TotalPerAll;
             From ;
                YourTalesTable ) RptTotal;
   where ;
       YourOtherJoinConditions;
      AND YourOtherTables.ItemID = PerItem.ItemID;
   order by ;
       whatever;
   into ;
       cursor YourReportResults

By doing an SQL-Select as your last 2 tables (one grouping by itemID) will create the total per item. By having the final where join only to the ItemID of the aliased PerItem, you'll get whatever that columns total was. However, since NO join on the aliased RptTotal, you'll get a Cartesian join... but since its always 1 record, each row will have the same value as its "TotalPerAll" column.

I hope these two solutions work for your needs.

锦欢 2024-09-08 03:27:45

首先,VFP 不支持字段级别的 case-when 构造。此外,您在字段级别的子选择在 from 表之后、where 之前、where 子句之后、order 之前有逗号...例如,

select * from MyTable, where SomeCondition, Order by ...

如果执行 VFP 报告,则无需手动添加行将您的组添加到原始数据中,这应该在报告本身中通过数据分组来完成,并将您的 ItemID 添加为组的基础。然后将“可求和”列复制/粘贴到每个项目的报告的组页脚区域中。双击该字段,并进行计算,告诉它 sum(),并在每个组的末尾重置(即:ItemID)。然后,包括一个报告摘要区域。这将为整个报告打印一次...与项目级别的摘要项目一样,再次复制/粘贴,但放入报告摘要区域中。双击这些元素进行 sum() 并在报告结束时重置。

但是,由于您在 VFP9 中运行,并且您可能希望转储数据以及已包含在各自位置中的行,因此我将分成单独的查询并将结果合并在一起,如下所示。预先提取报表数据的行项目支持,无需任何必要的聚合。

SELECT ;
        qItemSaleLines.ItemID, ; 
        qItemSaleLines.SaleID, ; 
        qCustomers.CardRecordID, ; 
        qItems.ItemNumber AS ProdCODE, ; 
        qItems.ItemName AS StkNAME, ; 
        qCustomers.LastName AS CUSTOMER, ; 
        qSales.InvoiceNumber AS SaleINVNo,  ; 
        qSales.InvoiceDate AS SaleDATE, ; 
        qItemSaleLines.Quantity AS SaleQTY, ; 
        qItemSaleLines.TaxExclusiveTotal AS SALE, ; 
        qItemSaleLines.CostOfGoodsSoldAmount AS COGS, ;  
        qItemSaleLines.TaxExclusiveTotal - qItemSaleLines.CostOfGoodsSoldAmount AS MARGIN, ; 
        (qItemSaleLines.TaxExclusiveTotal - qItemSaleLines.CostOfGoodsSoldAmount) / qItemSaleLines.TaxExclusiveTotal AS MPERCENT, ;
        "1" as TierLevel,;
        "1" as SubTier,;
        SPACE(50) as GroupCaption; 
    FROM ;
        qSales, ;
        qCustomers, ;  
        qItemSaleLines, ;
        qItems, ;
    WHERE ;
            qSales.CardRecordID = qCustomers.CardRecordID ;
        AND qSales.SaleID = qItemSaleLines.SaleID ;
        AND qItemSaleLines.ItemID = qItems.ItemID ;
        AND qSales.InvoiceDate > {^2009-06-30} ; 
    ORDER BY ;
        qItems.ItemNumber, ;
        qSales.InvoiceDate ; 
    INTO ;
        CURSOR C_TmpAllLineItemResults READWRITE 

*/ NOW, get your individual "ITEM GROUP" totals from ABOVE results...
SELECT ;
        TR.ItemID, ; 
        TR.ItemNumber AS ProdCODE, ; 
        TR.ItemName AS StkNAME, ; 
        "1" as TierLevel,;
        "2" as SubTier,;
        "Subtotal by " + TR.ItemNumber as GroupCaption; 
        SUM( TR.SaleQty ) as SaleQty,;
        SUM( TR.Sale ) as Sale,;
    FROM ;
        C_TmpAllLineItemResults TR;
    GROUP BY ;
        1, 2, 3, 4, 5, 6;
    ORDER BY ;
        1;
    INTO ;
        CURSOR C_SubTotalPerItem READWRITE 


*/ NOW, get your REPORT totals from ABOVE results...
SELECT ;
        "2" as TierLevel,;
        "Report Totals " as GroupCaption; 
        SUM( STBI.SaleQty ) as SaleQty,;
        SUM( STBI.Sale ) as Sale,;
    FROM ;
        C_SubTotalPerItem STBI;
    GROUP BY ;
        1, 2;
    INTO ;
        CURSOR C_ReportTotals READWRITE 

*/ Finally, merge them together... since the append from will add records with matching columns,
*/ even though a subtotal cursor doesn't have all the same columns, VFP doesn't care, just 
*/ adds for columns that DO match the table its going into.
SELECT C_TmpAllLineItemResults
APPEND FROM DBF( "C_SubTotalPerItem" )
APPEND FROM DBF( "C_ReportTotals" )

*/ Now, they are all merged... Finally, build an index for your report
INDEX on TierLevel + ItemID + SubTier TAG RptOrder

*/ Now, browse / review the order and adjust as needed...

First, VFP doesn't support a case-when construct at the field level. Additionally, your sub-select at the field level has comma after the from table and before the where, and after the where clause, before the order... such as

select * from MyTable, where SomeCondition, Order by ...

If doing a VFP report, you don't have to manually add lines to your groups into your raw data, that should be done in the report itself by datagrouping and add your ItemID as the basis of the group. Then have your "summable" columns copy/pasted into the group footer band of the report per item. Double click on the field, and for the calculation, tell it to sum(), and to reset at the end of each group (ie: ItemID). Then, include a report summary band. This prints once for the entire report... Like the summary items at the item level, copy/paste again, but put into the report summary band. Double click those elements to sum() and reset at the END OF REPORT.

However, since you are running in VFP9, and you might want to DUMP the data out with the lines already included in their respective positions, I would break into separate queries and merge the results together as I've sampled below. Pre-extract what would be the line-item support for the report data without any necessary aggregates.

SELECT ;
        qItemSaleLines.ItemID, ; 
        qItemSaleLines.SaleID, ; 
        qCustomers.CardRecordID, ; 
        qItems.ItemNumber AS ProdCODE, ; 
        qItems.ItemName AS StkNAME, ; 
        qCustomers.LastName AS CUSTOMER, ; 
        qSales.InvoiceNumber AS SaleINVNo,  ; 
        qSales.InvoiceDate AS SaleDATE, ; 
        qItemSaleLines.Quantity AS SaleQTY, ; 
        qItemSaleLines.TaxExclusiveTotal AS SALE, ; 
        qItemSaleLines.CostOfGoodsSoldAmount AS COGS, ;  
        qItemSaleLines.TaxExclusiveTotal - qItemSaleLines.CostOfGoodsSoldAmount AS MARGIN, ; 
        (qItemSaleLines.TaxExclusiveTotal - qItemSaleLines.CostOfGoodsSoldAmount) / qItemSaleLines.TaxExclusiveTotal AS MPERCENT, ;
        "1" as TierLevel,;
        "1" as SubTier,;
        SPACE(50) as GroupCaption; 
    FROM ;
        qSales, ;
        qCustomers, ;  
        qItemSaleLines, ;
        qItems, ;
    WHERE ;
            qSales.CardRecordID = qCustomers.CardRecordID ;
        AND qSales.SaleID = qItemSaleLines.SaleID ;
        AND qItemSaleLines.ItemID = qItems.ItemID ;
        AND qSales.InvoiceDate > {^2009-06-30} ; 
    ORDER BY ;
        qItems.ItemNumber, ;
        qSales.InvoiceDate ; 
    INTO ;
        CURSOR C_TmpAllLineItemResults READWRITE 

*/ NOW, get your individual "ITEM GROUP" totals from ABOVE results...
SELECT ;
        TR.ItemID, ; 
        TR.ItemNumber AS ProdCODE, ; 
        TR.ItemName AS StkNAME, ; 
        "1" as TierLevel,;
        "2" as SubTier,;
        "Subtotal by " + TR.ItemNumber as GroupCaption; 
        SUM( TR.SaleQty ) as SaleQty,;
        SUM( TR.Sale ) as Sale,;
    FROM ;
        C_TmpAllLineItemResults TR;
    GROUP BY ;
        1, 2, 3, 4, 5, 6;
    ORDER BY ;
        1;
    INTO ;
        CURSOR C_SubTotalPerItem READWRITE 


*/ NOW, get your REPORT totals from ABOVE results...
SELECT ;
        "2" as TierLevel,;
        "Report Totals " as GroupCaption; 
        SUM( STBI.SaleQty ) as SaleQty,;
        SUM( STBI.Sale ) as Sale,;
    FROM ;
        C_SubTotalPerItem STBI;
    GROUP BY ;
        1, 2;
    INTO ;
        CURSOR C_ReportTotals READWRITE 

*/ Finally, merge them together... since the append from will add records with matching columns,
*/ even though a subtotal cursor doesn't have all the same columns, VFP doesn't care, just 
*/ adds for columns that DO match the table its going into.
SELECT C_TmpAllLineItemResults
APPEND FROM DBF( "C_SubTotalPerItem" )
APPEND FROM DBF( "C_ReportTotals" )

*/ Now, they are all merged... Finally, build an index for your report
INDEX on TierLevel + ItemID + SubTier TAG RptOrder

*/ Now, browse / review the order and adjust as needed...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文