简体   繁体   中英

SQL query sum at bottom row

I am trying to get the sum of a column at the bottom row. I have tried a few examples by using SUM() and COUNT(), but they have all failed with syntax errors.

Here is my current code without any sum or anything:

:XML ON
USE MYTABLE
SELECT sbc.PolicyC.PolicyName as namn,COUNT(*) as cnt
FROM sbc.AgentC, sbc.PolicyC
WHERE sbc.AgentC.PolicyGuid = sbc.PolicyC.PolicyGuid
GROUP BY sbc.AgentC.PolicyGuid, sbc.PolicyC.PolicyName ORDER BY namn ASC
FOR XML PATH ('celler'), ROOT('root')
GO

The XML output is reformatted to become a regular HTML table.

EDIT:

Here is the latest code, but it generates a "sum" (same number as the row above) on every other row:

:XML ON
USE MYTABLE
SELECT sbc.PolicyC.PolicyName as namn,COUNT(*) as cnt
FROM sbc.AgentC, sbc.PolicyC
WHERE sbc.AgentC.PolicyGuid = sbc.PolicyC.PolicyGuid
GROUP BY sbc.AgentC.PolicyGuid, sbc.PolicyC.PolicyName with rollup
FOR XML PATH ('celler'), ROOT('root')
GO

The XML output looks like this:

<root>
<celler>
<namn>example name one</namn>
<cnt>23</cnt>
</celler>
<celler>
<cnt>23</cnt>
</celler>
<celler>
<namn>example name two</namn>
<cnt>1</cnt>
</celler>
<celler>
<cnt>1</cnt>
</celler>
</root>

Try

SELECT sbc.PolicyC.PolicyName as namn,COUNT(*) as cnt
FROM sbc.AgentC, sbc.PolicyC
WHERE sbc.AgentC.PolicyGuid = sbc.PolicyC.PolicyGuid
GROUP BY sbc.AgentC.PolicyGuid, sbc.PolicyC.PolicyName 
UNION
SELECT 'TOTAL' as nawn,COUNT(*) as cnt
FROM
FROM sbc.AgentC, sbc.PolicyC
WHERE sbc.AgentC.PolicyGuid = sbc.PolicyC.PolicyGuid
ORDER BY namn ASC

This will compute the total in a separate query. However, you might need to either add some non-printing, high-ASCII character to force the total to the bottom, or add some numeric ordering key... mySQL may also have an operator (similar to WITH ROLLUP in Microsoft SQL) which would be more efficient than the above code... So while this would work, there are probably more efficient options available to you...

MySQL supports a rollup extension to group by.

select * from parts;
+-----------+--------+
| part_name | amount |
+-----------+--------+
| upper     |    100 |
| lower     |    100 |
| left      |     50 |
| right     |     50 |
+-----------+--------+

select part_name
      ,sum(amount)
  from parts
 group 
    by part_name with rollup;

+-----------+-------------+
| part_name | sum(amount) |
+-----------+-------------+
| left      |          50 |
| lower     |         100 |
| right     |          50 |
| upper     |         100 |
| NULL      |         300 |
+-----------+-------------+

Updated to answer comments:

The following items list some behaviors specific to the MySQL implementation of ROLLUP:

When you use ROLLUP, you cannot also use an ORDER BY clause to sort the results. In other words, ROLLUP and ORDER BY are mutually exclusive. However, you still have some control over sort order. GROUP BY in MySQL sorts results, and you can use explicit ASC and DESC keywords with columns named in the GROUP BY list to specify sort order for individual columns. ( The higher-level summary rows added by ROLLUP still appear after the rows from which they are calculated, regardless of the sort order .)

My code became somthing like:

SELECT * FROM (...old code here... UNION ...'Total:' ... COUNT() ...)* z
ORDER BY CASE WHEN z.Namn = 'Total:' THEN '2' ELSE '1' END , z.Antal DESC

I have one column named Namn and one named Antal. If there is the value 'Total:' in the column Namn it will order that as a '2' and if not as a '1', that makes the 'Total:' move to the botton when I have decendent ordering on the Antal column.

The magic hapens because the 'Total:' is UNION with the table, and then the CASE statement at the end puts it at the end.

My complete code that works for me that is a loot moore messy, it unions 2 tables and stuff as well:

SELECT * FROM (
SELECT acrclient.Client_Name AS 'Namn', COUNT(x.client) AS 'Antal'  
FROM 
(SELECT 'B' tab,t.client
FROM asutrans t
where t.voucher_type!='IP' AND t.last_update >= {ts '2019-01-01 00:00:00'}  
UNION ALL SELECT 
'C' tab,t.client
FROM asuhistr t
WHERE t.voucher_type!='IP' AND t.last_update >= {ts '2019-01-01 00:00:00'} )  x
LEFT JOIN acrclient ON x.client = acrclient.client 
GROUP BY x.client, acrclient.Client_Name
UNION ALL
SELECT 'Total:', COUNT(client) FROM (SELECT 'B' tab,t.client
FROM asutrans t
where t.voucher_type!='IP' AND t.last_update >= {ts '2019-01-01 00:00:00'}  
UNION ALL SELECT 
'C' tab,t.client
FROM asuhistr t
WHERE t.voucher_type!='IP' AND t.last_update >= {ts '2019-01-01 00:00:00'} ) y
) z
ORDER BY CASE WHEN z.Namn = 'Total:' THEN '2' ELSE '1' END , z.Antal DESC

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM