SQL Select tables / list tables - sql

I would like to ask for help.
As I have 500 plus tables, and I need to search those table's column having some similar words. Is it possible to search and list those tables?
E.g
Table 1 - Name, age, height
Table 2 - Result, Name, Score
Table 3 - Name, Pic, Parent1, Parent2
I wan to do a query to select all the table that any of the column contain the word "%Name%", is this possible?

Just run following query in your db and replace your search string with string and it will work.
SQL for find particular word/value from all columns and tables in a database
DECLARE #SQL VARCHAR(MAX)
DECLARE #valueToFind VARCHAR(1000)
DECLARE #columnName VARCHAR(1000)
SET #valueToFind = 'string'
SET #columnName = '%%'
CREATE TABLE #TMP
(Clmn VARCHAR(500),
CNT INT)
SELECT #SQL=COALESCE(#SQL,'')+CAST('INSERT INTO #TMP Select ''' + TABLE_SCHEMA + '.' + TABLE_NAME + '.' + COLUMN_NAME + ''' AS Clmn, count(*) CNT FROM '
+ TABLE_SCHEMA + '.[' + TABLE_NAME +
'] WHERE [' + COLUMN_NAME + '] LIKE ''%' + #valueToFind + '%'' ;' AS VARCHAR(8000))
FROM INFORMATION_SCHEMA.COLUMNS
JOIN sysobjects B
ON INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = B.NAME
WHERE COLUMN_NAME LIKE #columnName AND xtype = 'U'
AND DATA_TYPE IN ('char','nchar','ntext','nvarchar','text','varchar')
--PRINT (#SQL)
EXEC(#SQL)
SELECT * FROM #TMP WHERE CNT > 0
DROP TABLE #TMP
-----------------------------------------------------------------------------------------

Related

SQL count distinct or not null for each column for many columns

I need to analyze a large table with hundreds of columns. A lot of columns are unused.
To investigate I could do something like
SELECT DISTINCT Column1
FROM myTable
or
WITH C AS
(
SELECT DISTINCT Column1
FROM MyTable
)
SELECT COUNT(*)
FROM C
Then I do the same for column2 and so on. However these queries only work for one column which is time consuming and does not give overview in one glance.
Any idea how to build such investigation query for all columns in one?
You need only 1 query where you have to list all the columns of the table:
SELECT COUNT(DISTINCT Column1) column1_count,
COUNT(DISTINCT Column2) column2_count,
COUNT(DISTINCT Column3) column3_count
.....................................
FROM MyTable;
For local purposes only, you can make it dynamic like this:
Get the columns of the table
the query is created as the colleagues did and then it is executed with the EXEC()
DECLARE #columns as Table(RowId INT IDENTITY(1,1), ColumnName nVarchar(50))
DECLARE #ii int = 0
DECLARE #max int = 0
DECLARE #sqlQuery nVarchar(MAX)
INSERT INTO #columns
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'Customer'
SET #sqlQuery = 'SELECT '
SELECT #max = COUNT(*) FROM #columns
WHILE #ii <= #max
BEGIN
SELECT #sqlQuery = CONCAT(#sqlQuery,'COUNT(DISTINCT ',ColumnName,') ',LOWER(ColumnName),'_count, ')
FROM #columns
WHERE RowId = #ii
SET #ii = #ii + 1
END
SELECT #sqlQuery = CONCAT(#sqlQuery,'FROM Customer')
SELECT #sqlQuery = REPLACE(#sqlQuery,', FROM',' FROM')
select #sqlQuery
EXEC (#sqlQuery)
You should flesh out your requirement a bit more. If all you want to know is if a column contains only NULLs, you'll want to check for max(ColumnName) is null
declare #sql table (id int identity(1,1), QueryString nvarchar(max))
create table ##emptyColumns (emptyColumn nvarchar(128))
declare #i int = 0
declare #iMax int
declare #runthis nvarchar(max)
insert #sql
select 'select ''' + QUOTENAME(s.name) + '.' + QUOTENAME(o.name) + quotename(c.name) + ''' as ''column''
from ' + QUOTENAME(s.name) + '.' + QUOTENAME(o.name) + '
having max(' + c.name + ') is null'
from sys.sysobjects o
inner join sys.syscolumns c on c.id = o.id
inner join sys.schemas s on s.schema_id = o.uid
where o.type = 'U'
order by s.name
, o.name
, c.colorder
select #iMax = count(*)
from #sql
print #iMax
while #i < #iMax
begin
set #i = #i + 1
select #runthis = 'insert into ##emptyColumns
' + QueryString
from #sql
where id = #i
execute sp_executesql #runthis
end
select *
from ##emptyColumns
drop table ##emptyColumns
One further option you might consider:
declare #sql nvarchar(max)
select #sql = isnull(#sql + ' union all ', '') + 'select ''' + COLUMN_NAME + ''',
sum(case when ' + COLUMN_NAME + ' is null then 1 else 0 end) as null_values,
count(distinct ' + COLUMN_NAME + ') as count_distinct
from ' + TABLE_SCHEMA + '.' + TABLE_NAME + '
'
from information_schema.columns
where TABLE_SCHEMA = 'MySchema' and TABLE_NAME = 'MyTable'
exec (#sql)
If you had very big tables with large numbers of columns and were only interested in empty columns you could look into something like checksum_agg(checksum(column_name)). It may help improve performance.
You'd need to be wary of column data types, as they are not all compatible with distinct.

Get data from tables that I have from another query

I'm trying to get data from all tables that I have from another query as follows:
DECLARE #count int
SET #count = (SELECT COUNT(*) FROM (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE '%Project%') AS SUBQUERY)
WHILE(#count!=0)
BEGIN
SELECT * from (SELECT TABLE_NAME from (SELECT TABLE_NAME,
ROW_NUMBER() over (order by table_name) as row_number
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '%Project%') as sub
WHERE row_number = #count) as another_sub;
SET #count = #count-1
end
What I get with this right now is 5 table names LIKE '%Project%'. I want to get the data from all of these 5 tables, not just their names. Also I don't want to join or union the tables. How can I achieve this?
DECLARE #SQL varchar(max) = '';
SELECT #SQL = #SQL + 'SELECT * FROM ' + QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) + ';' + CHAR(13) + CHAR(10)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '%Project%';
print #SQL;
--EXEC(#SQL);

Find count of items from all tables in SQL Server database (filter tables based on column name)

I have to find the total number of distinct items from a particular column (named Ticker) from all tables in the database.
How can I achieve this?. This is what I want:
Table_name | Column | Total_Tickers
------------+---------+---------------
Table_1 | ticker | 500
Table_2 | ticker | 100
Table_3 | ticker | 5000
.
.
I know I've got to use sp_MSForEachTable but I'm not sure how to filter those tables that do not have a Ticker column at all.
This is what I've tried:
create table #counts
(
table_name varchar(255),
ticker_count int
)
EXEC sp_MSForEachTable #command1='INSERT #counts (table_name, ticker_count)
SELECT ''?'', COUNT(ticker) FROM ? ',
#whereand = 'AND ''?'' IN (Select * from information_schema.columns where
column_name = ''%ticker%'')'
SELECT table_name, ticker_count
FROM #counts
ORDER BY table_name, ticker_count DESC
DROP TABLE #counts
It doesn't recognize the COUNT(ticker) on the 7th line since I'm not able to filter the tables!
I'd appreciate any pointers on this. Thanks
Here is a much easier approach
use your_databasename --replace with your database name
go
DECLARE #sql VARCHAR(max)= '',
#column_name SYSNAME = 'ticker'
SET #sql = Stuff((SELECT ' union all select Table_name = '''+ table_name + ''',[Column] = ''' + column_name
+ ''',Total_Tickers = count(distinct '+ column_name + ') from '
+ Quotename(table_catalog) + '.'+ Quotename(table_schema) + '.'+ Quotename(table_name)
FROM information_schema.columns
WHERE column_name = #column_name
FOR xml path('')), 1, 11, '') -- stuff is used to remove the first union all
--SELECT #sql
EXEC (#sql)
Since tables has to be filtered based on column name, I don't think msforeachtable would be helpful here.

No of records in each table [duplicate]

This question already has answers here:
Query to list number of records in each table in a database
(23 answers)
Closed 5 years ago.
How to get a list of all tables with no of records in a particular database in SQL Server.
Thanks
Here's another option - not dependent on INFORMATION_SCHEMA.
This would also allow you to alter your where clause (you may edit your #QUERY accordingly).
DECLARE #QUERY VARCHAR(MAX)
SET #QUERY = ''
/*
* Create a long query with a row count + table name.
* You may alter your where clause here
*/
SELECT #QUERY =
#QUERY + ' SELECT COUNT(*), ''' + QUOTENAME(name)
+ ''' FROM ' + QUOTENAME(name) + CHAR(13)
+ 'UNION ALL'
FROM sys.tables
--Get rid of the last 'UNION ALL'...
SELECT #QUERY = LEFT(#QUERY, LEN(#QUERY) - 10)
--Prepare a temp table - drop if exists and then create it
IF object_id('tempdb..#TableResults') IS NOT NULL
DROP TABLE #TableResults
CREATE TABLE #TableResults(
Count INT,
TableName VARCHAR(MAX)
);
--Insert the main query result into the temp table
INSERT INTO #TableResults
EXEC(#QUERY);
--Select all from the temp table
SELECT * FROM #TableResults
WHERE COUNT = 0
You will need to use Dynamic SQL and check for existance of rows in each table
declare #sql nvarchar(max)
select #sql = isnull(#sql + ' union all ' + char(13) , convert(nvarchar(max), ''))
+ 'select tbl_name = ''' + name + ''' '
+ 'where not exists (select * from ' + quotename(name) + ')'
from sys.tables
print #sql
exec (#sql)
Did you mean this
SELECT COUNT(*) FROM
INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME IN
(
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE')
Saravanan

Counting rows in the table which have 1 or more missing values

Could you please advise how to find the number of rows in the table which have 1 or more missing values? The missing values are represented in my table by question marks = '?'. The table has 15 columns and ~50k rows. When I run the following query for some of the columns I can receive some results:
SELECT
COUNT(*)
FROM table_name
WHERE column_name ='?'
However I have also columns which bring me result: "Error converting data type varchar to float"
I would like to be able to find the number of rows in the table which have 1 or more missing values using 1 query/not run separately for each column.
Thank you in advance for your support!
Select Count(*)
From mySchema.myTable
Where Cast(Col1 As NVarChar(128)) +
Cast(Col2 As NVarChar(128)) +
Cast(Coln As NVarChar(128)) Like '%?%'
It's ugly and WILL be slow and you may need to modify the Casts accordingly, but should do the trick.
This should work for any column:
select count(*)
from table_name
where column_name is null or cast(column_name as varchar(255)) = '?';
Try following query:
Just set table name and it will get all columns
Also you can give value_to_match like '?' in your case or any other if you want.
DECLARE #table_name nvarchar(max) = 'table_name'
DECLARE #value_to_match nvarchar(max) = '1'
DECLARE #query nvarchar(max) = ''
DECLARE #Condition nvarchar(max) = ' OR ' -- 1 OR when you want to count row if any column has that value -- 2 when you want all all columns to have same value
SELECT #query = #query + ' cast(' + COLUMN_NAME + ' as nvarchar(500)) = ''' + #value_to_match + '''' + #Condition FROM informatioN_schema.columns WHERE table_name = #table_name
if ##rowcount = 0
BEGIN
SELECT 'Table doesn''t Exists'
RETURN
END
SELECT #query = LEFT(#query,LEN(#query)-3)
PRINT ('select count(9) FROM ' + #table_name + ' WHERE ' + #query)
EXEC ('select count(9) FROM ' + #table_name + ' WHERE ' + #query)