Searching for a table based on values contained in the table - sql

I have a table with a reason_id foreign key. I need to map that back to its primary table. I have searched our databases for matching/similar column names but I wasn't able to find the table.
I have a list of values that would be associated with the reason_id. I'd like to search for tables that contain the list I have. Any help would be appreciated.
Here's the query I was running to search for columns:
select
t.name as Table_Name,
SCHEMA_NAME(schema_id) as schema_name,
c.name as Column_Name
from
sys.tables as t
inner join
sys.columns c
on
t.OBJECT_ID = c.OBJECT_ID
where
c.name like '%reason%'

There is no easy way to find the related data in other tables.
I'd try with tools such as ApexSQL Search or SQL Search. Both are free and you won’t go wrong with any of these.
If you want to do it with SQL only then identify all columns in all tables that have the same data type. To do so use sys.columns, sys.types and sys.tables views. Once you find all columns just try start writing queries for each table until you find the right one.
I’d go with something like this
select COUNT(*)
from tableX
where tableX.matchedColumn in
(
-- take 100 or more random rows from the original table
-- if result gives you a number that is near to the number of values listed here then you are most probably on the right track
)

Related

How to count specific column name in all tables of one SQL Server Database object

I want to count tables that have a specific column name. For instance, dbo.Management has 300 tables. Some tables have ProtectionKey column, and others don't.
I need a list of all the tables that have that column ProtectionKey, or at least a count of them.
I have looked into similar examples but those are either counting ALL columns in a DB or ALL columns in one table.
I would personally use the sys objects for this, as INFORMATION_SCHEMA can return incorrect information:
SELECT s.[name] AS SchemaName,
t.[name] AS TableName
FROM sys.schemas s
JOIN sys.tables t ON s.schema_id = t.schema_id
JOIN sys.columns c ON t.object_id = c.object_id
WHERE c.[name] = N'ProtectionKey';
Use INFORMATION_SCHEMA.COLUMNS:
select c.*
from INFORMATION_SCHEMA.COLUMNS c
where column_name = 'ProtectionKey';
This has many columns. The ones you want are TABLE_NAME and TABLE_SCHEMA.
Also, this only works in one database at a time, so you need to run it in each database where you want to search for the tables.

How to update column name after finding the table names from information schema

I have run a script to find the table names with a specific column name from a database using the information schema
here is the query
use IMS_SCMS_DIGITAL_POWER
select * from information_schema.columns
where column_name like 'COMPANY_ID%'
after finding the table names now i would like to update the specific column values of all the database. Need solutions.
Run following query to get all tablenames with specific column name
SELECT t.name AS TableName
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name LIKE '%COMPANY_ID%'
just use in forward only cursor with tablenames to update the specific table.

Read data from tables returned from inner query

So, I am working on a project where I need to find all tables that have the column xyz, and then remove all rows from such tables if the updated_at date for that row from that table is older than some duration.
I got the list of all tables from SQL Server like this:
SELECT
t.name AS table_name
FROM
sys.tables AS t
INNER JOIN
sys.columns c ON t.object_id = c.object_id
WHERE
c.name = 'xyz';
Now I want to use each of the tables returned from this query to DELETE all rows from these tables which satisfy some criteria. Can someone help me with the 'Nested query' please?
What you're contemplating isn't going to work; you need to explicitly specify which table you are deleting from in a delete statement.
My approach would be to use your query to dynamically generate the delete statements, then save the output of your query in a file, and run the file. This also gives you a chance to review and double-check the deletes before you run them, which is a good idea when you're making large-scale data changes like these.
select
'delete from ' + t.name + ' where updated_at <= ''2013-01-01'';'
from
sys.tables t
where
exists (select null from sys.columns c where c.object_id = t.object_id and c.name = 'xyz')
http://sqlfiddle.com/#!3/475c0/2

Compare 2 different tables columns from 2 different databases

I have a requirement to compare different tables' columns from 2 different databases, in order to add columns to the master tables based on the requirement.
For example:
Assume in master database I have created one table like:
create table test(id int,name varchar(10))
Assume in test database I have created one table like
create table testings(id int,name varchar(20), sal int)
now I have to compare 2 table columns
I don't want to use red-gate tools.
Can anyone help me?
Is it just red-gate tools you don’t want to use or basically any third party tool? Why not, even if you don’t have the budget to buy you can still use this in trial mode to get the job done?
We’ve been using Apex Diff tool but there are many more out there.
With so many tools available you can probably run all one by one in trial mode for months…
Knowing system tables and how to do this natively is great but it’s just too time consuming...
You can use the EXCEPT or INTERSECT set operators for this. Like so:
SELECT id, name FROM master.dbo.test
EXCEPT -- or INTERSECT
SELECT id, name FROM test.dbo.testings
This will give you:
EXCEPT: returns any distinct values from the left query that are not
also found on the right query.
INTERSECT: returns any distinct values that are returned by both the
query on the left and right sides of the INTERSECT operand.
In your case, since you want to select from two different databases, you have to use a fully qualified table names. They have to be in the form database.schema.object_name.
Update: If you want compare the two tables columns' names, not the data itself, you have to work with the metadata tables to compare the columns' names the same way with EXCEPT.
For instance, suppose you have two databases:
Test database contains the table:
create table test(id int, name varchar(10), dep varchar(50));
and another database:
anotherdatabase database contains the table:
create table testings(id int,name varchar(20), sal int);
And you want to compare the two tables' columns and get the tables that don't exist in the other table, in our example you need to get sal and dep.
Then you can do this:
SELECT ColumnName
FROM
(
SELECT c.name "ColumnName"
FROM test.sys.tables t
INNER JOIN test.sys.all_columns c
ON t.object_id = c.object_id
INNER JOIN test.sys.types ty
ON c.system_type_id = ty.system_type_id
WHERE t.name = 'test'
EXCEPT
SELECT c.name
FROM anotherdatabase.sys.tables t
INNER JOIN anotherdatabase.sys.all_columns c
ON t.object_id = c.object_id
INNER JOIN anotherdatabase.sys.types ty
ON c.system_type_id = ty.system_type_id
WHERE t.name = 'testings'
) t1
UNION ALL
SELECT ColumnName
FROM
(
SELECT c.name ColumnName
FROM anotherdatabase.sys.tables t
INNER JOIN anotherdatabase.sys.all_columns c
ON t.object_id = c.object_id
INNER JOIN anotherdatabase.sys.types ty
ON c.system_type_id = ty.system_type_id
WHERE t.name = 'testings'
EXCEPT
SELECT c.name
FROM test.sys.tables t
INNER JOIN test.sys.all_columns c
ON t.object_id = c.object_id
INNER JOIN test.sys.types ty
ON c.system_type_id = ty.system_type_id
WHERE t.name = 'test'
) t2;
This should give you:
Note that: I joined the tables:
databasename.sys.tables, and
databasename.sys.all_columns
with the table:
databasename.systypes
to get only those columns that have the same data type. If you didn't joined this table, then if two columns have the same name but different data type, they would be the same.
To compare columns use INFORMATION_SCHEMA.COLUMNS table in a SQL SERVER.
This is the exmaple:
select column_name from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='your_table_name1'
except
select column_name from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='your_table_name2'
This is a GPL Java program I wrote for comparing data in any two tables, with a common key and common columns, across any two heterogeneous databases using JDBC: https://sourceforge.net/projects/metaqa/
It intelligently forgives (numeric, string and date) data type differences by reducing them to a common format. The output is a sparse tab delimited file with .xls extension for use in a spreadsheet.

Accessing Database Meta Data

Im running into a tough issue. I have a database using Microsoft SQL 2008 and in this database there are many tables. The tables were auto generated and do not have meaningful names. There is one particular table that I need, and I can not seem to find it.
I know what the names of a few of the columns in the table are called. Is there a way I can go through all the tables one at a time looking at the names of the columns and seeing if they match the ones I know.
If they do, then I can look farther into it the table to see if it is the one I am looking for. Does this sound like a good approach to the problem? Is it possible? Any ideas of where to start?
SELECT OBJECT_SCHEMA_NAME([object_id]),
OBJECT_NAME([object_id])
FROM sys.columns
WHERE name IN ('column 1', 'column 2'
/* , ... other columns */);
EDIT by request, in case the OP meant to identify ALL vs. ANY:
SELECT OBJECT_SCHEMA_NAME([object_id), name
FROM sys.tables AS t
WHERE EXISTS
(
SELECT 1 FROM sys.columns
WHERE name = 'column 1'
AND [object_id] = t.[object_id]
)
AND EXISTS
(
SELECT 1 FROM sys.columns
WHERE name = 'column 2'
AND [object_id] = t.[object_id]
)
/* ... repeat for other columns ... */
Alternative to Aaron's answer using Information_schema.columns instead of sys.columns
SELECT Table_name
FROM
information_schema.columns
WHERE
column_name IN ('column 1', 'column 2')
GROUP BY Table_Name
Having COUNT(column_name) = 2
See this Data.SE query for a working example
With the scripts above, you are limited to SQL wild-carding, which can be pretty limited. You can use SchemaCrawler grep to more powerfully search through your database using regular expressions. SchemaCrawler also allows you additional features to to look for tables related by foreign keys, so for example, you can say find me all tables that have a customer address column, along with the tables that refer to these tables. SchemaCrawler is a command-line tool that is bundled with a Microsoft SQL Server database driver.
Sualeh Fatehi, SchemaCrawler