Avatar of N2012
N2012
 asked on

SQL query to count records in a set of tables

I'm trying to get a count of all SQL tables that start with "comp", but I also want to filter out the count to only records inside these tables that have "Type" column > 0 (some are null, I don't want to count them), and "List" column should be NULL. The query below will get me as far as the count by table name, but I can't figure out how to update the query so it filters the count based on the values as well.

SELECT t.name, s.row_count from sys.tables t
JOIN sys.dm_db_partition_stats s
ON t.object_id = s.object_id
AND t.type_desc = 'USER_TABLE'
AND t.name like 'comp%'
AND s.index_id IN (0,1)
Microsoft SQL ServerSQL

Avatar of undefined
Last Comment
N2012

8/22/2022 - Mon
PatHartman

Add a WHERE clause.  I moved the other criteria down to the WHERE clause since it doesn't belong in the join.

SELECT t.name, s.row_count from sys.tables t
JOIN sys.dm_db_partition_stats s
ON t.object_id = s.object_id
WHERE t.Type Is Not Null
AND t.List Is Null
AND t.type_desc = 'USER_TABLE'
AND t.name like 'comp%'
AND s.index_id IN (0,1)

PS - you didn't mention what table Type and List come from so I assumed "t".
aikimark

If you only need the count, there's no good reason to return any data other than count.  It is much more efficient
Select Count(*)

Open in new window

N2012

ASKER
The return is
  Invalid column name Type
  Invalid column name List

The first query I posted works, so 't' would suffice (you'd think!), but as stated originally, I'm still having trouble adding any "where" condition to it.
Your help has saved me hundreds of hours of internet surfing.
fblack61
N2012

ASKER
select count(*) works for individual tables, but very clunky if you have dozens of tables, especially if you want to run periodic queries.

I also tried
  select count(*) from tablename1
  union select count(*) from tablename2
  etc...
but after the results are skewed -- count is way off.
PatHartman

I'm still having trouble adding any "where" condition to it.
It is difficult to guess what might be the problem if you don't post the query and any error or a description of what is wrong with the result.
EugeneZ

try this
use yourDB

EXEC [sp_MSforeachtable] @command1='
IF (''?'' LIKE ''comp%]'')
BEGIN
 PRINT ''?''
 SELECT ''?'' TABLENAME,COUNT(*) CNT from ?
 where Type>0 and List is NULL END '
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
N2012

ASKER
Eugene Z, I tried your query and it's still a no go - the errors I get is as follows

Invalid column name 'Type'
Msg 207, Level 16, State 1, Line 6
Invalid column name 'List'
Msg 207, Level 16, State 1, Line 6
EugeneZ

are "type" "list" names  of columns in your tables?

you posted;
"also want to filter out the count to only records inside these tables that have "Type" column > 0 (some are null, I don't want to count them), and "List" column should be NULL.
N2012

ASKER
yes, they're column names
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
PatHartman

I think Type is a reserved word and List might also be.  It is always best to never use reserved words as column names even if the db engine allows it.

Try encasing the reserved words in single quotes or square brackets.
N2012

ASKER
I renamed the column names to pType and pList, I also updated the query with these new names, and still get the same error.
PatHartman

It would be helpful if you would post the complete query each time you modify it.
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
N2012

ASKER
EXEC [sp_MSforeachtable] @command1='
IF (''?'' LIKE ''comp%]'')
BEGIN
 PRINT ''?''
 SELECT ''?'' TABLENAME,COUNT(*) CNT from ?
 where pType>0 and pList is NULL END '

also tried the previous suggestion


SELECT t.name, s.row_count from sys.tables t
JOIN sys.dm_db_partition_stats s
ON t.object_id = s.object_id
WHERE t.pType Is Not Null
AND t.pList Is Null
AND t.type_desc = 'USER_TABLE'
AND t.name like 'comp%'
AND s.index_id IN (0,1)
EugeneZ

It is possible that some of your “Comp” tables do not have these columns.

Check your tables and search table criteria
N2012

ASKER
I reduced the query so only six tables would get queried (I added more characters to the tablename), and confirmed the tables all have these columns. Same error. Note - of the two columns - one of them has datatype INT and the other BIT -- would this make a difference?
I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck
EugeneZ

Try to run this against of table:
Select count(*) from your table where ..
EugeneZ

And post exact error text
N2012

ASKER
No error, I get an actual count that is accurate.

As I posted 3d ago, I also tried
  select count(*) from tablename1
  union select count(*) from tablename2
  etc...

after the first table or two, the results are skewed -- count is WAY off.
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
EugeneZ

Add “where yourcolum is null...” to your union t-sql
EugeneZ

And try the opposite with posted queries ( without “where”)
EugeneZ

If you got with “where” errors “ there are not such fields “
It means these tables do not have such fields
Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
N2012

ASKER
As I posted 3d ago, I also tried
  select count(*) from tablename1
  union select count(*) from tablename2
  etc...
this query does not get me the proper totals, even if I use a 'where' condition (columns are found), which is why I posted

I tried the suggested queries, but the column names are not found.

I use SSMS, SQL back end. What do you mean t-sql?
N2012

ASKER
I verified the columns specified in query exist in tables, so that's not the problem.
EugeneZ

Make sure that you ran in the right db
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
N2012

ASKER
Yep - confirmed.
EugeneZ

are you getting the expected result if you run?


use yourDB
EXEC [sp_MSforeachtable] @command1='
IF (''?'' LIKE ''comp%]'')
BEGIN
 PRINT ''?''
 SELECT ''?'' TABLENAME,COUNT(*) CNT from ?
 END '
N2012

ASKER
Only says "Query completed successfully." in the status bar at bottom of SSMS. Nothing shows up as a table.
All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
EugeneZ

It means it did not find “if-ed criteria” tables in this db an you remove ]from”if”?
EugeneZ

use yourDB
EXEC [sp_MSforeachtable] @command1='
IF (''?'' LIKE ''comp%'')
BEGIN
 PRINT ''?''
 SELECT ''?'' TABLENAME,COUNT(*) CNT from ?
 END '
EugeneZ

Try this one
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
N2012

ASKER
same thing -
sql1.png
EugeneZ

next try:


use yourDB
EXEC [sp_MSforeachtable] @command1='
IF (''?'' LIKE ''%comp%'')
BEGIN
 PRINT ''?''
 SELECT ''?'' TABLENAME,COUNT(*) CNT from ?
 END '
EugeneZ

try this -- it should work for you (just adjust  "WHERE" )

EXEC [sp_MSforeachtable]
@command1=
      '
      BEGIN
       PRINT ''?''
       SELECT ''?'' TABLENAME,COUNT(*) CNT from ? where type >2 and list >3
       END '
 ,@whereand =
       ' AND OBJECT_ID in ( select  t.object_id
       from sys.tables t inner join sys.columns c
       ON t.object_id=c.object_id
       where t.name like ''Comp%''
       and C.name in (''List'',''type''))'ee092929018PNG.PNG
This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
N2012

ASKER
Thanks, Eugene. This query's more complicated than I'm used to but it seems to be working. I'm getting counts for each table, but they are broken up in separate tables. My intention was to get the totals to show up in one table (kind of like a 'union select' would do) so I can later use them in a report. can this query be modified to join all totals together in one table?
ASKER CERTIFIED SOLUTION
EugeneZ

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
N2012

ASKER
It works!!!  :)
Many thanks!!!!!
N2012

ASKER
Thanks, Eugene!!!!
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.