How to aggregate database sizes into one total

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

barnescoAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
Olaf DoschkeConnect With a Mentor Software DeveloperCommented:
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
 
Jim HornMicrosoft SQL Server Developer, Architect, and AuthorCommented:
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
 
barnescoAuthor Commented:
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
What Kind of Coding Program is Right for You?

There are many ways to learn to code these days. From coding bootcamps like Flatiron School to online courses to totally free beginner resources. The best way to learn to code depends on many factors, but the most important one is you. See what course is best for you.

 
Scott PletcherSenior DBACommented:
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
 
Scott PletcherSenior DBACommented:
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
 
barnescoAuthor Commented:
Thanks, that worked
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.