UNION ALL to combine data across companies, with tables of same expression - sql

Is there by any chance a possibility to combine/union data from multiple tables, ending on the same characters in a SELECT statement?
We have several companies, built up with the same tables, and also the same column setup within the tables. For me to not making a UNION all statement, that includes all of the stores, I would like to know, if I could make a script, which does this for me.
Example of tables:
[Database].[dbo].[Company1$Sales Line]
[Database].[dbo].[Company2$Sales Line]
[Database].[dbo].[Company3$Sales Line]...
How I write the script today:
SELECT *
FROM [Database].[dbo].[Company1$Sales Line]
UNION ALL
SELECT *
FROM [Database].[dbo].[Company2$Sales Line]
UNION ALL
SELECT *
FROM [Database].[dbo].[Company3$Sales Line]...
I would think that there is an easier solution to do this.
Could probably be a WHILE loop statement - but I have no idea, what is the best practice, and if it's even possible. Otherwise I should make a VBA in Excel to assist me in doing this.
Thanks in advance :)

If you're after a way to generate the SQL you need on the fly, you can use the following as a basis, perhaps to build the content of a view which you can then query. Also note that generally, you don't specify 3 part names as you connect to the database in question. It's different of course for multiple databases, but that doesn't seem to be the case given your sample data.
select String_Agg(Concat('select * from ', QuoteName(Schema_Name(schema_id)), '.', QuoteName(name)), ' union all' + Char(13))
from sys.tables
where schema_id=Schema_Id('dbo') and name like 'Company%$Sales Line';

Related

Oracle SQL: single SELECT request for multiple owners

I would like your advice on the best method to use.
From a single Oracle server, we have 3 different owners that contain the exact same tables/data structures. Essentially, the owners allow us to separate the data by administrative regions.
Currently, when I want to do a SQL query on the entire data set (regions), I have to do 3 separate queries:
select * from owner1.Table1 union all
select * from owner2.Table1 union all
select * from owner3.Table1
In this simple example, there are no issues, but if the query is complex, it quickly becomes very difficult to maintain.
So, would there be a more efficient way to make only one global query instead of 3. I guess it's possible to do it via a PL/SQL script, or Dynamic SQL, but I don't know...
Basically, I would like to be able to do (where owners would contain the names of my 3 owners):
select * from owners.Table1
It is not possible to build views that would contain the data of all 3 owners (there would be too many).
Thanks
In this simple example, there are no issues, but if the query is complex, it quickly becomes very difficult to maintain.
So, would there be a more efficient way to make only one global query instead of 3.
Use a sub-query factoring clause (a.k.a. a CTE) to combine the queries with the simple UNION ALL queries and then perform the complex query on the combined table (rather than trying to perform the queries on the individual tables):
WITH subquery_name AS (
select * from owner1.Table1 union all
select * from owner2.Table1 union all
select * from owner3.Table1
)
SELECT <your complex query>
FROM subquery_name;

Select From Multiple and New Tables will be created

My Simple Query is
SELECT MAX(DATETIME)
FROM gss.dbo.contacts_23
WHERE Identification = ''
GROUP BY Identification
How can I select Max(date) from 25 tables and new tables can be created?
These tables like (contacts_22,contacts_25,contacts_29,contacts_36,.. and the new)
I tried to think as following
use union but what about the new tables will be created next time
select all tables start with 'contacts_' to fetch all these tables and the tables will be created next time
SELECT TABLE_NAME
FROM GSS.INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME like 'contacts_%'
but it's not doable with FROM clause
How can I do that GET MAX(DATE) FROM .... AND NEW TABLES
I'm using SQL Server 2012
Thanks in advance
The data model is horrible, and there is no clean way of achieving what you want.
The first way is to create a view which unions all your contacts_ tables, and then to run your query on that view.
Create view contacts_view as
select * from contacts_20
union
select * from contacts_21
...
This is the simplest solution, but only works if you can be certain that you're not creating more tables which need to be included in the view.
The alternative is to use dynamic SQL. This would use your query on the schema database to construct a SQL statement, which you then execute. This can get moderately complex, and is generally hard to test and debug, but does allow new tables to be automatically included in the results.

How schedule a job for a query which references multiple databases?

I have a query that I need to schedule to run on the first of every month. The query pulls data from two databases that have identical schema/structure but different data, and it unions them together.
My problem is that the SSMS scheduler requires that I designate a database, which seems to indicate that I can only query against one db at a time.
Querying against multiple databases is a fairly common task so I would think there has to be a way to automate this but I have not been able to find anything thus far.
Is there a way to do this? Do I have to use SSIS?
Any help would be greatly appreciated.
Use three part name.
use tempdb
go
select 'master', count(*) as 'total' from [master].sys.objects
union
select 'msdb', count(*) as 'total' from msdb.sys.objects
union
select 'tempdb', count(*) as 'total' from tempdb.sys.objects
go

Trying to pull from multiple tables and multiple columns within tables

I have tried this query to pull up multiple tables and columns it works but comes back blank.
select * from onshore.contracting where code between 18789 and 18798;
select * from onshore.safety_incident where code between 18789 and 18798;
For your immediate problem, the following SQL will work if you really want all the data:
select * from onshore.contracting where code between 18789 and 18798;
select * from onshore.safety_incident where code between 18789 and 18798;
... and so on.
These tables probably have different columns so you need a separate select statement for each one.
If you are going to do more with SQL then it really would be worthwhile to learn it. There is a free resource here: https://www.w3schools.com/sql, my contribution is at http://www.thedatastudio.net and there are many others. It is a bit dangerous to use SQL without understanding it.

Union tables with different schema

I am referring to Jordan's answer regarding "dealing with evolving schemas "Dealing with evolving schemas.
As I share similar problem I have tried to query tables with different schema and got the following results:
Select a,b,c
FROM (Select 1 as a, 2 as b), --Test_a
(Select 1 as a, 2 as b, 3 as c), --Test_b
runs fine...
I have put Test_a and Test_b into physical tables (all fields are nullable) and tried:
Select a,b,c
FROM (Select a,b, from BI_WORKSPACE.Test_a),
(Select a,b,c from BI_WORKSPACE.Test_b)
It also runs fine
but when i tried
Select a,b,c
FROM BI_WORKSPACE.Test_a,
BI_WORKSPACE.Test_b
It failed...
Is there a bug, something i do wrong?
the last sample is the one i am after as it allows me to "evolve" my schema over time. i would like to avoid altering schema of all existing tables whenever i add a column to support a new business need.
Many thanks for your help.
The reason for asking:
We hold our data in "Daily tables" so when querying we pay only for the period we are interested in.
As BQ doesn’t support "Dynamic SQL", we have created an offline process that takes a query template and generates a query for desired period. Something like:
Input:
Select a,b,c FROM [<Source>]
Output:
Select a,b,c FROM [MYDATASET.TABLE20140201], [MYDATASET.TABLE20140202], [MYDATASET.TABLE20140203], [MYDATASET.TABLE20140204] , [MYDATASET.TABLE20140205] , [MYDATASET.TABLE20140206] , [MYDATASET.TABLE20140207]
Our process is unaware of the query logic. Sometimes we add fields to support evolving business needs.
Using dynamic sub selects will complicate staff a lot, and altering the schema for all hundreds of existing tables is expensive and prone to mistakes.
Any suggestions?
I don't think the last query should work. You're asking for columns a,b, and c from two tables, but one of those tables doesn't have a column with that name. That looks like a query error to me, since you are explicitly asking for a column that doesn't exist on the table.
There is a workaround -- to use a subselect -- which you noticed, if you know that a field may be missing from one schema. The other workaround, of course, is to update the schema.
This seems like it is working as intended. If you don't agree, can you let me know why?
It's possible to select from union of tables with different schemas.
Simple trick is to use subquery with asterisk as Jordan proposed. There's no need to alter schema.
In your case this will work (legacy SQL dialect)
SELECT a,b,c
FROM ( SELECT * FROM BI_WORKSPACE.Test_a ),
( SELECT * FROM BI_WORKSPACE.Test_b )