I have this query:
select t.table_schema,
t.table_name,
c.column_name
from information_schema.tables t
inner join information_schema.columns c
on c.table_name = t.table_name
and c.table_schema = t.table_schema
where c.column_name like '%column_name%'
and t.table_schema not in ('information_schema', 'pg_catalog')
and t.table_type = 'BASE TABLE'
order by t.table_schema;
Is there somewhere I can actually search for a specific value and see under which column & table & schema it falls under?
For example,
I would like to search for a value 'WINNER' and find out which columns contain this value (and obviously the table and schema as well)
and the column might be STATUS with value WINNER and under table CUSTOMER and schema ALL_DATA
Can anyone help please?
There is no straight forward way to do this, there is no build-in functionality in any DBMS as far as I know. One way how to do this would be to create SQL which selects all text-like columns and generates another SQL. There is an example:
select 'select '''||t.table_schema||''' as table_schema, '''||
t.table_name||''' as table_name, '''||
c.column_name||''' as column_name,'||
' count(*) as occurrences'
' from '||t.table_schema||'.'||t.table_name||
' where '||c.column_name||' like ''WINNER'''
||' union all '
from information_schema.tables t
inner join information_schema.columns c
on c.table_name = t.table_name
and c.table_schema = t.table_schema
where c.column_name like '%column_name%'
and t.table_schema not in ('information_schema', 'pg_catalog')
and t.table_type = 'BASE TABLE'
and c.data_type = 'character varying'
order by t.table_schema;
According to limitations set in query it will generate as much rows as columns you want to search. Copy this result block in your client (delete 'union all' from last row)
and execute. Try to limit rows as much as possible for better performance. Due to columnar data store Redshift will execute this quite effectively, keep in mind that on row-oriented DBMS performance for such approach will be much worse.
Related
I am new to PostgreSQL. Actually I want to change all the email addresses in all the tables to some fake email address. Like I want that abc#gmail.com should become abc#1234gmail.com, xyz#hotmail.com should become xyz#1234hotmail.com and so on.
I found the query that gives the tables that have email column in it. Here is the query
select t.table_schema, t.table_name
from information_schema.tables t
inner join information_schema.columns c on c.table_name = t.table_name and c.table_schema = t.table_schema
where c.column_like '%email%'
and t.table_schema not in ('information_schema', 'pg_catalog')
and t.table_type = 'BASE TABLE'
order by t.table_schema;
It is giving me some records. Now one way is go to each table and alter the values of the email column. But can I modify the above query to also get the value of each email and change it to some fake address. Like if email value is abc#gmail.com then just append 12345 or any value after the # sign of each email address. So each email value becomes abc#1234gmail.com, xyz#1234hotmail.com and etc
You can build a set of update queries for each column as below -
select concat('update ', t.table_schema, '.', t.table_name, ' set ', c.column_name, ' = replace(', c.column_name, ', ''#'', ''#1234'') ')
from information_schema.tables t
inner join information_schema.columns c on c.table_name = t.table_name and c.table_schema = t.table_schema
where c.column_name like '%email%'
and t.table_schema not in ('information_schema', 'pg_catalog')
and t.table_type = 'BASE TABLE' order by t.table_schema;
This query would build one update statement per column that uses replace function to replace '#' with '#1234'. I haven't fully tested it, but hope it gives you an approach to work with.
I would like to execute a SQL query to find all tables within a database that does not have a particular column?
E.g. I would like a list of tables that do not have a column called 'BranchID'.
Thank you for your attention.
Information Schema Views contain metadata about the database. For more information, go here
Using these views you can do something like this...
SELECT
t.TABLE_NAME
FROM
INFORMATION_SCHEMA.TABLES AS t
WHERE NOT EXISTS
(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS AS c WHERE c.TABLE_NAME = t.TABLE_NAME AND c.COLUMN_NAME = 'BranchID')
select table_name
from INFORMATION_SCHEMA.COLUMNS
except
select table_name
from INFORMATION_SCHEMA.COLUMNS
where column_name = 'BranchID'
(from memory, I might have the column names wrong but should get you most of the way there :) )
This should work.
SELECT table_name
FROM INFORMATION_SCHEMA.columns c
WHERE NOT EXISTS (
SELECT table_name
FROM INFORMATION_SCHEMA.columns cc
WHERE cc.table_name = c.table_name
AND cc.column_name = 'Branch_id'
)
First of all, we select the table_name from Information_Schema.Columns where the table_name is NOT in a query that selects tables WITH the Branch_ID Column
You can use the INFORMATION_SCHEMA.COLUMNS table and INFORMATION_SCHEMA.TABLES table to get the information you want using normal SQL Queries.
In your case you would use a subquery:
select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_NAME NOT IN (select TABLE_NAME from INFORMATION_SCHEMA.COLUMNS where COLUMN_NAME='BranchID')
I have created a re-usable procedure that could help you.
CREATE PROC SP_UTIL_findcolumns
#SearchString As varchar(250) = NULL
AS
BEGIN
SELECT
t.TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES AS t
WHERE NOT EXISTS
(SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS AS c
WHERE c.TABLE_NAME = t.TABLE_NAME
AND c.COLUMN_NAME = #SearchString )
END
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
ORDER BY TABLE_NAME ASC
I am using this code to print the table names of a db. What I want to do is print the table name and the col names in each table. Can I do this by nesting a statement.
This code is being run on a SQL Server in a query window.
I tried this
SELECT COL_NAME
FROM
(SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
ORDER BY TABLE_NAME ASC)
Any ideas?
This should do it:
SELECT C.TABLE_NAME, C.COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS C
WHERE EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES T
WHERE T.TABLE_TYPE='BASE TABLE' AND C.TABLE_NAME=T.TABLE_NAME)
ORDER BY C.TABLE_NAME, C.COLUMN_NAME
In Sqlserver 2005 INFORMATION_SCHEMA views was introduced first.
These views are mainly created to get the metadata like table name,
column name, datatype of columns etc. about tables, columns, views,
domains etc.
Each and every database contains these views. If you want to check what's going on behind the scene you can check the logic of these views by doing just sp_helptext. Like
sp_helptext INFORMATION_SCHEMA.COLUMNS
By using above views you can get your desired result. Please check below query.
SELECT T.TABLE_NAME,C.COLUMN_NAME,C.DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS C
INNER JOIN INFORMATION_SCHEMA.TABLES T ON C.TABLE_NAME = T.TABLE_NAME
AND C.TABLE_SCHEMA = T.TABLE_SCHEMA
WHERE T.TABLE_TYPE = 'BASE TABLE'
With Mssql 2008 version try the following query. This itemise column name and the tables they belong to.
SELECT c.name AS 'ColumnName', t.name AS 'TableName'
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name = c.name
ORDER BY TableName, ColumnName;
If I know I need to JOIN Table 4 onto Table 1, but they have no columns in common, it takes some effort to find a Table 2 that has Column A in common with Table 1, then a Table 3 that has Column B in common with both Table 2 and Table 4, and so on, to eventually be able to pull that Table 4 into the query.
It sometimes requires joining a handful of unnecessary tables to get two joined that need joined. Maybe that's a necessary evil with some table setups, but how would you query so that SQL would create that path for you to save the trouble of figuring it out?
Edit:
What about this? (Thanks to AHiggins for getting me on this track)
SELECT
CASE
WHEN B.COLUMN_NAME = C.COLUMN_NAME
THEN D.COLUMN_NAME + ' is on both ' + A.TABLE_NAME + ' and ' + D.TABLE_NAME
ELSE 'ZZZNULLZZZ'
END AS 'QuickJoin',
A.TABLE_NAME AS 'Starting Table',
B.COLUMN_NAME AS 'Column 1',
B.TABLE_NAME AS 'Linking Table',
C.COLUMN_NAME AS 'Column 2',
D.TABLE_NAME AS 'Destination Table'
FROM
INFORMATION_SCHEMA.COLUMNS A
JOIN
INFORMATION_SCHEMA.COLUMNS B ON
A.COLUMN_NAME = B.COLUMN_NAME AND
A.TABLE_NAME <> B.TABLE_NAME
JOIN
INFORMATION_SCHEMA.COLUMNS C ON
B.TABLE_NAME = C.TABLE_NAME AND
A.TABLE_NAME <> C.TABLE_NAME
JOIN
INFORMATION_SCHEMA.COLUMNS D ON
C.COLUMN_NAME = D.COLUMN_NAME AND
D.TABLE_NAME NOT IN (A.TABLE_NAME, B.TABLE_NAME, C.TABLE_NAME)
WHERE
-- Starting Table
A.TABLE_NAME = 'Starting Table'
-- Possible Column 1
-- AND B.COLUMN_NAME = 'siteid'
-- Possible Linking Table
-- AND B.TABLE_NAME = 'possibleLinkingTable'
-- Possible Column 2
-- AND C.COLUMN_NAME = 'possibleColumn2'
-- Destination Table
AND D.TABLE_NAME = 'Destination Table'
ORDER BY
QuickJoin, B.COLUMN_NAME, B.TABLE_NAME, C.COLUMN_NAME
There isn't an automatic solution to this - however, there are things you might try that will help point you in the right direction.
One way, if your database is set up well, might be to look at what foreign keys are set up in the database.
Another tool that might help would be checking to see what other tables have columns in common with either your source or destination.
SELECT A.TABLE_NAME, A.COLUMN_NAME, B.TABLE_NAME
FROM
INFORMATION_SCHEMA.COLUMNS A
INNER JOIN
INFORMATION_SCHEMA.COLUMNS B ON
A.COLUMN_NAME = B.COLUMN_NAME AND
A.TABLE_NAME <> B.TABLE_NAME
WHERE A.TABLE_NAME = 'YourStartingTable' OR B.TABLE_NAME = 'YourDestinationTable'
Ultimately, you'll still need to go through the results yourself - but these two queries might help speed the time spent looking around.
how to get all the tables and structure in a database in a table format using an sql query or stored procedure?
Structure is like below:
Sl No FieldName DataType Size Description
1 UserName varchar 50
This should do the trick. There is a bit more information in here but I think you may find it useful.
Select t.Table_Schema,
t.Table_Name,
c.Column_Name,
IsNull(c.Column_Default, '') as 'Column_Default',
c.Is_Nullable,
c.Data_Type,
IsNull(c.Character_Maximum_Length, IsNull(Numeric_Precision,'') + IsNull(Numeric_Scale, IsNull(DateTime_Precision,''))) as 'Size'
From Information_Schema.Tables t
Join Information_Schema.Columns c on t.Table_Catalog = c.Table_Catalog
And t.Table_Schema = c.Table_Schema
And t.Table_Name = c.Table_Name
Where t.Table_Type = 'BASE TABLE'
Order by t.Table_Schema, t.Table_Name, c.Ordinal_Position