Solved

How to aggregate database sizes into one total

Posted on 2016-07-14
6
50 Views
Last Modified: 2016-07-14
How would you aggregate (total) all returned rows into one number. I have so far the embedded code. Thanks

DECLARE @SQL VARCHAR(MAX)
SELECT @SQL = COALESCE(@SQL + CHAR(13) + 'UNION ALL
' ,'') + 'SELECT ' +
'sum(size * 8 /1024.0)/1000 AS GB from ' + QUOTENAME(name) + '.dbo.sysfiles'
FROM sys.databases
ORDER BY name
 
EXECUTE (@SQL)

Open in new window

0
Comment
Question by:barnesco
6 Comments
 
LVL 65

Expert Comment

by:Jim Horn
ID: 41710893
Not really following your code, but if you have a query with UNION ALL and want an aggregate value, one way is to throw the whole thing into a subquery and then sum.  For example

SELECT SUM(a.companies) as the_total
FROM (
  SELECT COUNT(name) as companies FROM whorehouses
  UNION ALL
  SELECT COUNT(name) FROM burgerjoints) a

Open in new window

0
 

Author Comment

by:barnesco
ID: 41710913
I'm trying to find the sum of all database sizes distilled into one number. I did accidentally include some extra code, so this will clean it up:

DECLARE @SQL VARCHAR(MAX)
SELECT @SQL = COALESCE(@SQL + CHAR(13) + 'UNION ALL
' ,'') + 'SELECT ' + 'sum(size * 8 /1024.0)/1000 AS GB from .dbo.sysfiles'
FROM sys.databases
 
EXECUTE (@SQL)

Open in new window

0
 
LVL 69

Expert Comment

by:Scott Pletcher
ID: 41710966
Here's some points to consider along with the code below:

1) I've separated data size and log size, as log size can vary considerably over time (esp. if you shrink log files a lot: definitely not recommended, but many people still do it).

2) dbo.sysfiles is such an ancient view that I switched to using sys.database_files instead

3) You might want to consider tempdb separately, although for now I left it in the totals.


SELECT data_size_gb, log_size_gb, data_size_gb + log_size_gb AS total_gb
FROM (
    SELECT
        CAST(SUM(CASE WHEN df.type_desc = 'LOG' THEN 0 ELSE df.size END) / 128.0 / 1000.0 AS decimal(9, 3)) AS data_size_gb,
        CAST(SUM(CASE WHEN df.type_desc = 'LOG' THEN df.size ELSE 0 END) / 128.0 / 1000.0 AS decimal(9, 3)) AS log_size_gb
    FROM sys.database_files df
) AS derived
0
Is Your AD Toolbox Looking More Like a Toybox?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.

 
LVL 29

Accepted Solution

by:
Olaf Doschke earned 500 total points
ID: 41711003
What did you do? It is essential to prefix .dbo.sysfiles with each database name and you removed that part of the code. Your first code was correct, you just need to sum all the values  after unioning.

DECLARE @SQL VARCHAR(MAX)
SELECT @SQL = COALESCE(@SQL + CHAR(13) + 'UNION ALL
' ,'') + 'SELECT ' +
'sum(size * 8 /1024.0)/1000 AS GB from ' + QUOTENAME(name) + '.dbo.sysfiles'
FROM sys.databases

EXECUTE ('Select Sum(DBSizes.GB) as InstanceGB FROM ('+@SQL+') as DBSizes')

Open in new window


Bye, Olaf.
0
 
LVL 69

Expert Comment

by:Scott Pletcher
ID: 41711053
CORRECTION:
I needed to use "sys.master_files" rather than "sys.database_files".
There is sometimes a slight lag before the sys.master_files view reflects db size changes, but it shouldn't really be significant, and a query against master_files will run much faster.


SELECT data_size_gb, log_size_gb, data_size_gb + log_size_gb AS total_gb
FROM (
    SELECT
        CAST(SUM(CASE WHEN mf.type_desc = 'LOG' THEN 0 ELSE mf.size END) / 128.0 / 1000.0 AS decimal(9, 3)) AS data_size_gb,
        CAST(SUM(CASE WHEN mf.type_desc = 'LOG' THEN mf.size ELSE 0 END) / 128.0 / 1000.0 AS decimal(9, 3)) AS log_size_gb
    FROM sys.master_files mf
) AS derived
1
 

Author Closing Comment

by:barnesco
ID: 41711113
Thanks, that worked
0

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Marketers need statistics and metrics like everybody else needs oxygen. In this article we explain how to enable marketing campaign statistics for Microsoft Exchange mail.
This article shows gives you an overview on SQL Server 2016 row level security. You will also get to know the usages of row-level-security and how it works
Using examples as well as descriptions, and references to Books Online, show the documentation available for datatypes, explain the available data types and show how data can be passed into and out of variables.
Viewers will learn how the fundamental information of how to create a table.

810 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question