Reputation: 23
I have database with 7,000 tables, most of these have a column DataAreaId
, but not all tables, since some are global.
I would like to list all tables that have the column DataAreaId
and their row count where the column DataAreaId
contains "FR".
So for one table it would be:
SELECT COUNT(*)
FROM Table
WHERE DataAreaId = 'FR'
Any suggestions?
Upvotes: 0
Views: 716
Reputation: 12014
One way to do this is to query all tables containing that column, and build a query statement for each
select 'union all select ' + QUOTENAME(t.name,N'''') + ', count(1) from ' + t.name + ' where Dataareaid = ''FR'''
from sys.columns c
join sys.tables t ON c.object_id = t.object_id
where c.name = 'Dataareaid'
each row would look like this
union all select 'SomeTable', count(1) from SomeTable where Dataareaid = 'FR'
Now just put all statements together and remove the first union all
Upvotes: 0
Reputation: 877
My answer gets the column metadata, executes the statement in a loop and publishes the results to a table variable:
if object_id('tempdb..#LoopList') is not null
drop table #LoopList
select
s.[name] as SchemaName
,t.[name] as TableName
,row_number() over (order by t.[object_id] asc) as RowNumber
into #LoopList
from sys.columns as c
inner join sys.tables as t
on c.[object_id] = t.[object_id]
inner join sys.schemas as s
on t.[schema_id] = s.[schema_id]
where c.[name] = 'Dataareaid'
declare
@a int = 1
,@b int = (select max(RowNumber) from #LoopList)
,@c nvarchar(max)
,@d nvarchar(max)
,@e int
declare @count table (RowCounter int)
declare @resultsTable table (TableName nvarchar(500), RowCounter int)
while @a <= @b
begin
delete from @count
set @c = concat ((select quotename(SchemaName) from #LoopList where RowNumber = @a)
,'.'
,(select quotename(TableName) from #LoopList where RowNumber = @a)
)
set @d = concat(N'select count(*) from '
,@c
,N' where Dataareaid = ''FR'''
)
insert into @count (
RowCounter
)
exec sp_executesql @d
set @e = (select top 1 RowCounter from @count)
insert into @resultsTable (
TableName
,RowCounter
)
values (@c,@e)
set @a += 1;
end
select * from @resultsTable
Upvotes: -1
Reputation: 14928
You can use the following
CREATE TABLE T1(
Dataareaid VARCHAR(45)
);
CREATE TABLE T2(
Dataareaid VARCHAR(45)
);
INSERT INTO T1 VALUES
('FR'),
('ALG'),
('FR');
DECLARE @SQL NVARCHAR(max) = N'';
SELECT @SQL = (
SELECT CONCAT(
N'UNION ALL ',
N'SELECT ''',
t.name,
N''' AS TableName, ',
N'Cnt = (SELECT COUNT(1)',
' FROM ',
QUOTENAME(t.name),
N' WHERE [Dataareaid] = ''FR'')'
)
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name = 'Dataareaid'
FOR XML PATH('')
)
SET @SQL = STUFF(@SQL, 1, 10, N'');
EXEC sp_executesql @SQL;
Returns:
+-----------+-----+
| TableName | Cnt |
+-----------+-----+
| T1 | 2 |
| T2 | 0 |
+-----------+-----+
Upvotes: 4