SQL inner join based on table name pattern - sql

On this legacy SQL Database with hundreds of tables, I need to do a inner join on all tables whose name follows a format:
barX_foo_bazX
barX_foo_bazY
barZ_foo_bazZ
I would like to inner join all tables with foo in their name
I am not sure this is possible at all.
Clearly, with this syntax it is not (but it may help understand what I'm aiming at):
USE [LegacyDB_Name]
SELECT *
FROM '%_foo_%' inner join '%_foo_%'
where my_stuff_is(some condition)
Any Suggestions? Ideas on how I can do this? Maybe there is an easier path this young padawan is not seeing...
Many Thanks!

I am not sure this is possible at all.
Nope, table names cannot contain or use wildcards, they must be strings.
My advice would be to find whatever program makes these select queries and include whatever pattern matching you need in the queries in there.
But your finished query must contain table names as strings.

Maybe the simplest way to do this is to declare a cursor based on the below query and build a dynamic sql query. Research tsql cursor and dynamic sql execution and it should be fairly simple.
SELECT *
FROM information_schema.tables
Where Table_Type = 'Base Table' And Table_Name Like '%_foo_%'

If your tables all have the same structure (i.e. columns), then you could do this in two steps.
Generate the SQL statement:
select 'UNION ALL SELECT ''' + table_name + ''' AS table_name, * FROM '
+ table_name AS stmt
from information_schema.tables
where table_type = 'BASE TABLE'
and table_catalog = 'LegacyDB_Name'
and table_name LIKE '%foo%';
The output will be something like:
stmt
--------------------------------------------------------------------
UNION ALL SELECT 'barX_foo_bazX' AS table_name, * FROM barX_foo_bazX
UNION ALL SELECT 'barX_foo_bazY' AS table_name, * FROM barX_foo_bazY
UNION ALL SELECT 'barX_foo_bazZ' AS table_name, * FROM barX_foo_bazZ
From this output, copy the SQL rows and remove the first 2 words (UNION ALL) from the first line. This is a valid SQL statement.
Execute the SQL statement derived above
If you need this SQL more often, then create a view for it:
CREATE OR REPLACE VIEW all_foo AS
SELECT 'barX_foo_bazX' AS table_name, * FROM barX_foo_bazX
UNION ALL SELECT 'barX_foo_bazY' AS table_name, * FROM barX_foo_bazY
UNION ALL SELECT 'barX_foo_bazZ' AS table_name, * FROM barX_foo_bazZ;
Now you can query like
SELECT * FROM all_foo WHERE ...

Related

Is there a way I create a SQL view of multiple tables based on a query of the table schema?

I have a SQL database where there are multiple tables maintained by other people which I would like to join up to create a view. The trouble is the number of tables keeps expanding! The columns and character lengths are the same.
I can get as far as creating a list of the tables by using
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE 'Table%'.
At the moment I have a union all query like the below
SELECT * FROM table1
UNION ALL
SELECT * FROM table2;
but the table list keeps growing. Is there any I can create something to loop thought the tables? Something like
*SELECT * FROM (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE 'Table%') UNION ALL*
I know that wouldn't work but I'm hoping there's some sort of trick to get to go all the way! This is on SQL Server 2012 if that helps.
Thanks
declare #s nvarchar(max);
set #s=''
select
#s=#s +'(select * from [' + s.name + '])'+
case when ROW_NUMBER() over (order by s.name) != count(*) over ()
then
' UNION ALL '
else
''
end
from
sys.tables as s
where s.name like 't%'
print #s;
There is a bit more to think about, you need to make sure the field counts are the same before hand also to be on the safe side, may be best to avoid select * and use field names that you require. This should produce the SQL statement to run in a stored proc as detailed in the comments. Spend some time error trapping this and doing neccessary checks for continuity in the field names as mentioned.

Retrieve schema name from view definition

In Snowflake, I retrieve different views with the following SQL query:
SELECT * FROM "myDatabase"."mySchema"."VIEWS"
That returns a table with these columns notably:
TABLE_ID
TABLE_NAME
TABLE_SCHEMA_ID
TABLE_SCHEMA
TABLE_CATALOG_ID
TABLE_CATALOG
TABLE_OWNER
VIEW_DEFINITION
For each VIEW_DEFINITION column entries, I am trying to extract all the strings <Schema_Name>.<View_Name> (or at least the <Schema_Name>).
Is it possible to do that with a SQL query (or by any other way)?
Edit
The table I obtain using the initial query is as follows:
TABLE_ID
TABLE_NAME
TABLE_SCHEMA_ID
TABLE_SCHEMA
TABLE_CATALOG_ID
TABLE_CATALOG
TABLE_OWNER
VIEW_DEFINITION
0001
MY_TABLE_NAME
99
MY_TABLE_SCHEMA
20
PMY_TABLE_CATALOG
MY_OWNER_VIEWS_ADMIN
…
where the VIEW_DEFINITION column contains queries like the one below:
"CREATE OR REPLACE VIEW My_Table_Schema_VIEWS.My_Table_Name AS
WITH STUDY_SITE_SCOPE AS (
SELECT
...
FROM (
SELECT
A.SUBJECT_NUMBER
, A.SUBJECT_STATUS
FROM <Schema_Name>.<View_Name_1> X
JOIN <Schema_Name>.<View_Name_2> Y
...
)
JOIN (
SELECT
...
FROM <Schema_Name>.<View_Name_3> X
JOIN <Schema_Name>.<View_Name_4> Y
...
)
..."
From this VIEW_DEFINITION I am trying to extract all the <Schema_Name>.<View_Name_XX> strings (or at least the <Schema_Name>).
I assume you want to get all base schemas your current view is built on top of.
To answer your question short: Yes, it is.
Maybe the following procedure is giving you an idea on how to solve it via SQL or a Stored Procedure:
Query the view definition
Search for all strings within the view definition that follow the "FROM" or "JOIN" clause
Extract them and probably check for the database name in front of the schema name
You can use information_schema.tables:
select t.*
from information_schema.tables t
where t.table_type = 'VIEW'

List all table names without knowing the database name within my machine

I am using SQl Server 2014, and Normally we can list out tables if we knew the DB name as :
USE YOURDBNAME
GO
SELECT *
FROM sys.Tables
GO
But I want to know all the tables irrespective of db's that are present on my machine
Or can I go for looping by listing out all DB name.(EXEC sp_databases)
Is there any better way to find out this?
There are several ways of getting all tables in your database
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'
OR
SELECT * FROM Sys.Tables
OR
SELECT * FROM INFORMATION_SCHEMA.TABLES
OR
SELECT sobjects.name FROM sysobjects sobjects WHERE sobjects.xtype = 'U'
Docs for all the xtypes
select * from tab
or
select * from * cat
The first one will show the associated CLUSTERID with tables for the current user.
I think you need
SELECT name FROM master.sys.databases
and then you will need to create a cursor query (for your USE XXXX) to iterate through the following query.
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'

Vertica Dynamic Max Timestamp from all Tables in a Schema

System is HP VERTICA 7.1
I am trying to create a SQL query which will dynamically find all particular tables in a specific schema that have a Timestamp column named DWH_CREATE_TIMESTAMP from system tables. (I have completed this part successfully)
Then, pass this list of tables to an outer query or some kind of looping statement which will select the MAX(DWH_CREATE_TIMESTAMP) and TABLE_NAME from all the tables in the list (200+) and union all the results together into one list.
The expected output is a 2 column table with all said tables with that TS field and the max of each value. Tables are constantly being created and dropped, so the point is to make everything totally dynamic where no TABLE_NAME values are ever hard-coded.
Any idea of Vertica specific ways to accomplish this without UDF's would be greatly appreciated.
Inner Query (working):
select distinct(table_name)
from columns
where column_name = 'DWH_CREATE_TIMESTAMP'
and table_name in (select DISTINCT(table_name) from all_tables where schema_name = 'PTG_DWH')
Outer Query (attempted - not working):
SELECT Max(DWH_CREATE_DATE) from
WITH table_name AS (
select distinct(table_name)
from columns
where column_name = 'DWH_CREATE_DATE' and table_name in (select DISTINCT(table_name) from all_tables where schema_name = 'PTG_DWH'))
SELECT MAX(DWH_CREATE_DATE)
FROM table_name
Thanks!!!
No way to do that in one SQL .
You can used the below method for node max timestamp columns values
select projections.anchor_table_name,vs_ros.colname,max(max_value) from vs_ros,vs_ros_min_max_values,storage_containers,projections where vs_ros.colname ilike 'timestamp'
and vs_ros.salstorageid=storage_containers.sal_storage_id
and vs_ros_min_max_values.rosid=vs_ros.rosid
and storage_containers.projection_name=projections.projection_name
group by projections.anchor_table_name,vs_ros.colname

What is the Select statement to return the column names in a table

Is there any select statement to return the list of columns in the table?
The INFORMATION_SCHEMA.COLUMNS view will provide the column names for a particular table name.
SELECT Column_Name + ', '
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Table_Name'
There are several other views as well as the one above which you may find useful. These INFORMATION_SCHEMA views provide information on the schema of your database.
Select top 10 * from Information_Schema.tables
Select top 10 * from Information_Schema.views
Select top 10 * from Information_Schema.routines
Select top 10 * from Information_Schema.parameters
Paul's answer is right for mysql. ON EDIT: and sql server too, apparently. Arrgh. Sorry Paul.
For sql server, you want sys.syscolumns, very similarly to this answer:
How do I look at column metadata in Sybase?
sp_help TableName
Will give you all columns, plus lots of other information.
You can also get column data in SqlServer 2005 using
SELECT column_name 'Column Name',
data_type 'Data Type'
FROM information_schema.columns
WHERE table_name = 'table name'
Srinivas Dontula.
sdonthula#live.com