How to merge multiple access database with similar column field - sql

I have multiple MS Access (.mdb) databases which consist of exactly the same fields, a big database has been split into multiple parts to make it manageable.
I have imported all of the .mdb files into MS SQL Server but I don't know how to merge them all into one big database, or if that's not possible, then how to make a query so that it will search from all the databases and return the result.
Let me give an example to make myself more clear:
I have part1.mdb, part2.mdb, part3.mdb, ..., part50.mdb files.
All of the files contain the fields:
name
mobile no
address
city
state
Now if I have to search certain mobile no then I have to search in all of the files which is very tedious.

the best approach would be to create one table possibly with partitioning (for instance: by date). But lets concentrate on generating one table from many.
I believe that you have multiple tables like table1, table2 ... table50
if that is the case
SELECT * INTO myBigtable FROM
(
SELECT * FROM table1 union all
SELECT * FROM table2 union all
SELECT * FROM table3 union all
...
SELECT * FROM table50
) T;
don't forget to create proper indexes on it

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;

Snowflake sql table name wildcard

What is a good way to "select" from multiple tables at once when the list of tables is not known in advance in snowflake sql?
Something that simulates
Select * from mytable*
which would fetch same results as
Select * from mytable_1
union
Select * from mytable_2
...
I tried doing this in a multistep.
show tables like 'mytable%';
set mytablevar =
(select listagg("name", ' union ') table_
from table(result_scan(last_query_id())))
The idea was to use the variable mytablevar to store the union of all tables in a subsequent query, but the variable size exceeded the size limit of 256 as the list of tables is quite large.
Even if you do not hit 256 character limits, it will not help you to query all these tables. How will you use that session variable?
If you have multiple tables which have the same structure, and hold similar data that you need to query together, why are the data not in one big table? You can use Snowflake's clustering feature to distribute data based on a specific column to your micro-partitions.
https://docs.snowflake.com/en/user-guide/tables-clustering-micropartitions.html
Anyway, you may create a stored procedure which will create/replace a view.
https://docs.snowflake.com/en/sql-reference/stored-procedures-usage.html#dynamically-creating-a-sql-statement
And then you can query that view:
CALL UPDATE_MY_VIEW( 'myview_name', 'table%' );
SELECT * FROM myview_name;

Difference between two tables, unknown fields

Is there a way in Access using SQL to get the difference between 2 tables?
I'm building an audit function and I want to return all records from table1 where a value (or values) doesn't match the corresponding record in table2. Primary keys will always match between the two tables. They will always contain the exact same number of fields, field names, and types, as each other. However, the number and name of those fields cannot be determined before the query is run.
Please also note, I am looking for an Access SQL solution. I know how to solve this with VBA.
Thanks,
There are several possibilities to compare fields with known names, but there is no way in SQL to access fields without knowing their name. Mostly becase SQL doesn't consider fields to have a specific order in a table.
So the only way to accomplish what you need in pure Access-SQL would be, if there was a SQL-Command for it (kind of like the * as placeholder for all fields). But there isn't. Microsoft Access SQL Reference.
What you COULD do is create an SQL-clause on the fly in VBA. (I know, you said you didn't want to do it in VBA - but this is doing it in SQL, but using VBA to create the SQL..).
Doing everything in VBA would probably take some time, but creating an SQL on the fly is very fast and you can optimize it to the specific table. Then executing the SQL is the fastest solution you can get.
Not sure without your table structure but you can probably get that done using NOT IN operator (OR) using WHERE NOT EXISTS like
select * from table1
where some_field not in (select some_other_field from table2);
(OR)
select * from table1 t1
where not exists (select 1 from table2 where some_other_field = t1.some_field);
SELECT A.*, B.* FROM A FULL JOIN B ON (A.C = B.C) WHERE A.C IS NULL OR B.C IS NULL;
IF you have tables A and B, both with colum C, here are the records, which are present in table A but not in B.To get all the differences with a single query, a full join must be used,like above

Temporarily create a row?

I'm looking to use some data, but the data doesn't have a row. I'm supposed to do this without creating a row in the table, so is there a way I can create a row only for the query I'm using and not the main table? I don't have access to creating rows on the table.
Here's the Data I am trying to use. I get it by using a formula on some of the existing data.
Select <Columns>
From<Table>
left join (select sum(case when number = '440' then amount end)
/sum(case when number ='430' then amount end) GP from <table>)
on <relations>
I need to use it in one of the columns. I want to create a small little row that will only be active on this query, and won't appear in the main database. I don't have access to edit the main database. Can I create it in this query?
Is it possible?
If it isn't possible, let me know via an answer, and that will close the question.
I am not sure if this is what you want (I need more details to understand the problem), but you can easily add rows with UNION ALL for example:
SELECT numberOfThings,
TypeOfThings
FROM thingsTable tt
UNION ALL
SELECT 24, 'Fake Type of Things'
This way, this will only be within your query and not in the DB.
(You can use this in your subqueries)
If this helps you can read further about combining queries here.
You can use a common table expression to make a virtual table that appears to have an additional row of your choosing for purposes of select.
For example, create the real table:
create user foo login;
create table dont_touch ( x text);
insert into dont_touch values ('one fish'),('two fish'), ('red fish');
revoke all on dont_touch from foo;
grant select on dont_touch to foo ;
Then log in as "foo" and do:
with t as (select * from dont_touch union all select 'blue fish')
select * from t;
However, queries upon this t might not be able to benefit from indexes that exist on the underlying real table, so the queries might be much slower.

Select * from n tables

Is there a way to write a query like:
select * from <some number of tables>
...where the number of tables is unknown? I would like to avoid using dynamic SQL. I would like to select all rows from all the tables that (the tables) have a specific prefix:
select * from t1
select * from t2
select * from t3
...
I don't know how many t(n) might there be (might be 1, might be 20, etc.) The t table column structures are not the same. Some of them have 2 columns, some of them 3 or 4.
It would not be hard using dynamic SQL, but I wanted to know if there is a way to do this using something like sys.tables.
UPDATE
Basic database design explained
N companies will register/log in to my application
Each company will set up ONE table with x columns
(x depends on the type of business the company is, can be different, for example think of two companies: one is a Carpenter and the other is a Newspaper)
Each company will fill his own table using an API built by me
What I do with the data:
I have a "processor", that will be SQL or C# or whatever.
If there is at least one row for one company, I will generate a record in a COMMON table.
So the final results will be all in one table.
Anybody from any of those N companies will log in and will see the COMMON table filtered for his own company.
There would be no way to do that without Dynamic SQL. And having different table structures does not help that at all.
Update
There would be no easy way to return the desired output in one single result set (result set would have at least the same # of columns of the table with most columns and don't even get me started on data types compatibility).
However, you should check #KM.'s answer. That will bring multiple result sets.
to list ALL tables you could try :
EXEC sp_msforeachtable 'SELECT * FROM ?'
you can programmability include/exclude table by doing something like:
EXEC sp_msforeachtable 'IF LEFT(''?'',9)=''[dbo].[xy'' BEGIN SELECT * FROM ? END ELSE PRINT LEFT(''?'',9)'