Select all tables with at least one row of data inserted - sql

I want return all tables that have at least one row of data.
I was using this:
SELECT DISTINCT(OBJECT_NAME(OBJECT_ID))
FROM SYS.DM_DB_PARTITION_STATS ST
WHERE ST.ROW_COUNT > 0 AND OBJECT_ID > 100
But I don't want use the table SYS.DM_DB_PARTITION_STATS.
I want to know another way to find these tables?
Any clues?
thanks.

You could use something like this:
SELECT
t.NAME AS TableName,
p.rows AS RowCounts
FROM
sys.tables t
INNER JOIN
sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN
sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
WHERE
t.is_ms_shipped = 0
AND p.rows > 0
GROUP BY
t.Name, p.Rows
ORDER BY
t.Name
That would list all tables with the name and number of rows (> 0) in them.
And it doesn't use sys.dm_db_partition_stats ....

You should not use sys.dm_db_partition_stats

Related

SQL multiple tables reach

I have this chunk of code here, thing is it query selected "TestLog" and shows:
name,
schema,
rowcount,
totalspace,
usedspace,....
Thing is I need this information to be queried for more than one table, lets say a 5 specific ones... can anyone help out?
USE myDB
GO
SELECT
t.name AS TableName,
s.name AS SchemaName,
p.rows AS RowCounts,
SUM(a.total_pages) * 8 / 1024 AS TotalSpaceMB,
SUM(a.used_pages) * 8 / 1024 AS UsedSpaceMB,
(SUM(a.total_pages) - SUM(a.used_pages)) * 8 / 1024 AS UnusedSpaceMB
FROM
sys.tables t
INNER JOIN sys.indexes i ON t.object_id = i.object_id
INNER JOIN sys.partitions p ON i.object_id = p.object_id AND i.index_id = p.index_id
INNER JOIN sys.allocation_units a ON p.partition_id = a.container_id
LEFT OUTER JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE
t.name = ('TestLog')
AND t.is_ms_shipped = 0
AND i.object_id > 255
GROUP BY
t.name, s.name, p.rows
ORDER BY
t.name;
GO
It works as below:
-- specific tables
WHERE
t.name in ('Test1' , 'Test2' , 'Test3')
AND t.is_ms_shipped = 0
AND i.object_id > 255
-- one specific table
WHERE
t.name = 'TestLog'
AND t.is_ms_shipped = 0
AND i.object_id > 255
-- specific tables with test in front
WHERE
t.name like 'Test%'
AND t.is_ms_shipped = 0
AND i.object_id > 255

SqlServer - Get all tables that has data ( are not empty )

The question is simple:
Is it possible to retrive all the tables that are not empty ?
I need a query to list the tables. Is there a way ?
Thanks to support
Try this Script To get all tables with non empty records
USE [Your database Name]
Go
SELECT SCHEMA_NAME(schema_id) AS [SchemaName],
[Tables].name AS [TableName]
--SUM([Partitions].[rows]) AS [TotalRowCount]
FROM sys.tables AS [Tables]
JOIN sys.partitions AS [Partitions]
ON [Tables].[object_id] = [Partitions].[object_id]
AND [Partitions].index_id IN ( 0, 1 )
-- WHERE [Tables].name = N'name of the table'
GROUP BY SCHEMA_NAME(schema_id), [Tables].name
HAVING SUM([Partitions].[rows]) >0
Slightly different than #Sreenu131 answer as it is using sys.partitions .rows property to find
p.rows > 0
SELECT
sch.name as SchemaName,
t.NAME AS TableName,
p.rows AS RowCounts
FROM
sys.tables t
INNER JOIN
sys.partitions p ON t.object_id = p.OBJECT_ID
INNER JOIN sys.schemas sch
on t.schema_id = sch.schema_id
WHERE
t.NAME NOT LIKE 'dt%'
AND t.is_ms_shipped = 0
AND p.rows > 0
GROUP BY
sch.name,t.Name, p.Rows
ORDER BY
sch.name,t.Name

Records not shown while selecting from table in mssql

I'm Getting total tables in whole database and its row-count from following query:
SELECT SCHEMA_NAME(A.schema_id) + '.' +
A.Name, SUM(B.rows) AS 'RowCount'
FROM sys.objects A
INNER JOIN sys.partitions B ON A.object_id = B.object_id
WHERE A.type = 'U'
GROUP BY A.schema_id, A.Name
Order By 'RowCount' desc
After that i'm getting below result:
And then finally when i'm trying to fetch records from one of this table
select * from dbo.[xxx_$Retail ICT Header]
It gives 0 rows as output......Any clue?
To get the Row count in each table try below query and after that cross check by running select query.
SELECT s.name+'.'+o.name,
ddps.row_count
FROM sys.indexes AS i
INNER JOIN sys.objects AS o ON i.OBJECT_ID = o.OBJECT_ID
INNER JOIN sys.schemas s on s.schema_id= o.schema_id
INNER JOIN sys.dm_db_partition_stats AS ddps ON i.OBJECT_ID = ddps.OBJECT_ID
AND i.index_id = ddps.index_id
WHERE i.index_id < 2 AND o.is_ms_shipped = 0 ORDER BY o.NAME

Count(*) differs from rows in sys.partitions

I'm using the following query to get information about all tables in a DB:
SELECT
t.NAME AS TableName,
i.name as indexName,
sum(p.rows) as RowCounts,
sum(a.total_pages) as TotalPages,
sum(a.used_pages) as UsedPages,
sum(a.data_pages) as DataPages,
(sum(a.total_pages) * 8) / 1024 as TotalSpaceMB,
(sum(a.used_pages) * 8) / 1024 as UsedSpaceMB,
(sum(a.data_pages) * 8) / 1024 as DataSpaceMB
FROM
sys.tables t
INNER JOIN
sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN
sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN
sys.allocation_units a ON p.partition_id = a.container_id
WHERE
t.NAME NOT LIKE 'dt%' AND
i.OBJECT_ID > 255 AND
i.index_id <= 1
GROUP BY
t.NAME, i.object_id, i.index_id, i.name
ORDER BY
object_name(i.object_id)
The problem is that for some tables it reports a different row count than if I do:
select count(*) FROM someTable
Why is that?
Edit:
The first query returns a higher count:
First: 1 240 464
Second: 413 496
The problem is that there's more than one allocation_unit per partition, so the same partition can appear more than once and therefore the sum(p.rows) ends up counting the same partition more than once, so you get a multiple of the right number of rows.
Here's how I solved the problem:
(note that my query isn't identical to yours, I have slightly different columns and used Kb rather than Mb, but the idea is the same)
SELECT
s.Name + '.' + t.name AS table_name,
(select sum(p2.rows)
from sys.indexes i2 inner join sys.partitions p2 ON i2.object_id = p2.OBJECT_ID AND i2.index_id = p2.index_id
where i2.object_id = t.object_id and i2.object_id > 255 and (i2.index_id = 0 or i2.index_id = 1)
) as total_rows,
SUM(CASE WHEN (i.index_id=0) OR (i.index_id=1) THEN a.total_pages * 8 ELSE 0 END) AS data_size_kb,
SUM(CASE WHEN (i.index_id=0) OR (i.index_id=1) THEN a.used_pages * 8 ELSE 0 END) AS data_used_kb,
SUM(CASE WHEN (i.index_id=0) OR (i.index_id=1) THEN 0 ELSE a.total_pages * 8 END) AS index_size_kb,
SUM(CASE WHEN (i.index_id=0) OR (i.index_id=1) THEN 0 ELSE a.used_pages * 8 END) AS index_used_kb,
SUM(a.total_pages) * 8 AS total_size_kb,
SUM(a.used_pages) * 8 AS total_used_kb,
SUM(a.used_pages) * 100 / CASE WHEN SUM(a.total_pages) = 0 THEN 1 ELSE SUM(a.total_pages) END AS percent_full
FROM
sys.tables t
INNER JOIN
sys.schemas s ON s.schema_id = t.schema_id
INNER JOIN
sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN
sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN
sys.allocation_units a ON p.partition_id = a.container_id
WHERE
t.is_ms_shipped = 0 AND i.OBJECT_ID > 255
GROUP BY
t.object_id, t.Name, s.Name
ORDER BY SUM(a.total_pages) DESC
From the sys.partitions documentation
rows bigint Approximate number of rows in this partition.
(emphasis mine). The system views aren't going to keep a spot-on number of rows in the table. Think of what that would entail and how much overhead it would add to all insert/delete statements. If I were a betting man, I'd say that it's doing something with the count of the number of pages in the clustered index or heap which is a far cheaper operation. That's purely speculative, though.
Have you looked into the help article regarding the sys.allocation_units view? Apparently, the container_id field is a little more than it seems. Try to add this to the where section:
and a.type = 2
In SQL Server 2016, To fix the count(*) and sys.partitions mismatch I performed an Index Rebuild on the Primary Key. Luckily the TABLE only had 2.4 million rows so it didn't take that long as I have standard edition so couldn't do the rebuild ONLINE.
Inner joins will cause unmatched rows to be filtered out. Groups will also affect your row counts as they can combine rows. These two conditions were cause a lower row count for the aggregate query than the simple count(*).
I see specifically you're asking about the sys.partitions table. The likely explanation is that there is not a match for every row in the sys.indexes table given the match condition of i.object_id = p.OBJECT_ID AND i.index_id = p.index_id. Try running this:
Select
count(*)
from
sys.partitions p
LEFT JOIN
sys.indexes i ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
You will then likely see the count you expect. Remove the count function to simply Select * ... to find the unmatched rows.

Row count for tables in a specific schema [duplicate]

This question already has answers here:
Get counts of all tables in a schema
(6 answers)
Closed 9 years ago.
How to get a sql query which will get me all the tables with their respect row counts within one schema
Below is the Microsoft SQL Server query to retrieve all Tables what the schema is for the table and the amount of rows.
to use for specific schema simply uncomment the last row of there where clause(remove /**/). and enter the schema names that you are looking for in the brackets on the last row of the where clause you can enter more then 2 just simply follow the pattern 'SchemaName','SchemaName','SchemaName'.
SELECT
t.NAME AS TableName,
s.name AS SchemaName,
p.[Rows]
FROM
sys.tables t
INNER JOIN
sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN
sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN
sys.schemas s on s.schema_id = t.schema_id
WHERE
t.NAME NOT LIKE 'dt%' AND
i.OBJECT_ID > 255 AND
i.index_id <= 1 /* AND
s.name in ('Schemaname1','Schemaname2') */
GROUP BY
t.NAME, i.object_id, i.index_id, i.name,s.name, p.[Rows]
ORDER BY
object_name(i.object_id)
if you would like to query like this
SELECT owner, table_name, NUM_ROWS FROM ALL_TABLES where owner like 'Schema_name'
I would suggest creating a view like so.
CREATE VIEW ALL_TABLES
AS
SELECT
t.NAME AS table_name,
s.name AS owner,
p.[Rows] as NUM_ROWS
FROM
sys.tables t
INNER JOIN
sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN
sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN
sys.schemas s on s.schema_id = t.schema_id
WHERE
t.NAME NOT LIKE 'dt%' AND
i.OBJECT_ID > 255 AND
i.index_id <= 1 /* AND
s.name in ('Schemaname1','Schemaname2') */
GROUP BY
t.NAME, i.object_id, i.index_id, i.name,s.name, p.[Rows]
ORDER BY
object_name(i.object_id)
and then if you run the following query it will work
SELECT owner, table_name, NUM_ROWS FROM ALL_TABLES where owner like 'Schema_name'
If this helps please mark the answer as correct