Netezza create table by union 2 tables - netezza

I am trying to create (CTAS) a table in Netezza using
Create table A as (select * from B union select * from C)
I am getting an error cross database access not supported although all the tables reside on the same database.
Any pointers.

In netezza, the only kind of ‘cross database access’ that is NOT supported is ‘writing’.
Unlike SQLserver you need to switch you ‘current database’ to the one where table A is going to land before you run the query.

Related

Joining tables from two Oracle databases in SAS

I am joining two tables together that are located in two separate oracle databases.
I am currently doing this in sas by creating two libname connections to each database and then simply using something like the below.
libname dbase_a oracle user= etc... ;
libname dbase_b oracle user= etc... ;
proc sql;
create table t1 as
select a.*, b.*
from dbase_a.table1 a inner join dbase_b.table2 b
on a.id = b.id;
quit;
However the query is painfully slow. Can you suggest any better options to speed up such a query (short of creating a database link going down the path of creating a database link)?
Many thanks for looking at this.
If those two databases are on the same server and you are able to execute cross-database queries in Oracle, you could try using SQL pass-through:
proc sql;
connect to oracle (user= password= <...>);
create table t1 as
select * from connection to oracle (
select a.*, b.*
from dbase_a.schema_a.table1 a
inner join dbase_b.schema_b.table2 b
on a.id = b.id;
);
disconnect from oracle;
quit;
I think that, in most cases, SAS attemps as much as possible to have the query executed on the database server, even if pass-through was not explicitely specified. However, when that query queries tables that are on different servers, different databases on a system that does not allow cross-database queries or if the query contains SAS-specific functions that SAS is not able to translate in something valid on the DBMS system, then SAS will indeed resort to 'downloading' the complete tables and processing the query locally, which can evidently be painfully inefficient.
The select is for all columns from each table, and the inner join is on the id values only. Because the join criteria evaluation is for data coming from disparate sources, the baggage of all columns could be a big factor in the timing because even non-match rows must be downloaded (by the libname engine, within the SQL execution context) during the ON evaluation.
One approach would be to:
Select only the id from each table
Find the intersection
Upload the intersection to each server (as a scratch table)
Utilize the intersection on each server as pass through selection criteria within the final join in SAS
There are a couple variations depending on the expected number of id matches, the number of different ids in each table, or knowing table-1 and table-2 as SMALL and BIG. For a large number of id matches that need transfer back to a server you will probably want to use some form of bulk copy. For a relative small number of ids in the intersection you might get away with enumerating them directly in a SQL statement using the construct IN (). The size of a SQL statement could be limited by the database, the SAS/ACCESS to ORACLE engine, the SAS macro system.
Consider a data scenario in which it has been determined the potential number of matching ids would be too large for a construct in (id-1,...id-n). In such a case the list of matching ids are dealt with in a tabular manner:
libname SOURCE1 ORACLE ....;
libname SOURCE2 ORACLE ....;
libname SCRATCH1 ORACLE ... must specify a scratch schema ...;
libname SCRATCH2 ORACLE ... must specify a scratch schema ...;
proc sql;
connect using SOURCE1 as PASS1;
connect using SOURCE2 as PASS2;
* compute intersection from only id data sent to SAS;
create table INTERSECTION as
(select id from connection to PASS1 (select id from table1))
intersect
(select id from connection to PASS2 (select id from table2))
;
* upload intersection to each server;
create table SCRATCH1.ids as select id from INTERSECTION;
create table SCRATCH2.ids as select id from INTERSECTION;
* compute inner join from only data that matches intersection;
create table INNERJOIN as select ONE.*, TWO.* from
(select * from connection to PASS1 (
select * from oracle-path-to-schema.table1
where id in (select id from oracle-path-to-scratch.ids)
))
JOIN
(select * from connection to PASS2 (
select * from oracle-path-to-schema.table2
where id in (select id from oracle-path-to-scratch.ids)
));
...
For the case of both table-1 and table-2 having very large numbers of ids that exceed the resource capacity of your SAS platform you will have to also iterate the approach for ranges of id counts. Techniques for range criteria determination for each iteration is a tale for another day.

IF option in sqlite returning syntax error [duplicate]

I need to create a temp table (which is a copy of Employees table) in a SQLite database, provided the table by the name of 'Employees' exists. There are only 2 columns in Employees table - EmployeeId (integer) and EmployeeName (varchar(100)).
Is there any way to implement the above using SQLite SQL?
Pseudo-code for intended SQL, which does not work in SQlite is as below. I hope there was something as powerful as the pseudo-code below in SQLite.
--if Employees table exists then create a temp table and populate it with all
--rows from Employees table
CREATE TEMP TABLE tempEmployees if exists Employees as select * from Employees;
SQLite has almost no control logic; as an embedded database, it is designed to be used together with a 'real' programming language.
You could just try to copy the data, and ignore the errors:
try:
c.execute("CREATE TEMP TABLE tempEmployees AS SELECT * FROM Employees")
except:
pass
However, this would also suppress any other errors.
A better idea is to check explicitly whether the table exists:
c.execute("SELECT 1 FROM sqlite_master WHERE type='table' AND name='Employees'")
if c.fetchone():
c.execute("CREATE TEMP TABLE tempEmployees AS SELECT * FROM Employees")

How can we query data from two different databases and compare the results using SQL Server?

Suppose I have two databases located on the same server. How can we write the query part in sql server to extract data from two different databases located on the same server.
Use 3 part naming: [DatabaseName].[SchemaName].[TableName]
select
t1.*,
t2.*
from [MyDatabase].[dbo].[MyTable] t1
join [MyOtherDatabase].[dbo].[MyOtherTable] t2 on t1.SomeColumn = t2.SomeColumn
Fully qualify the table with DB_NAME.Schema_name.table_name. For example, if you have database as DB1 and DB2 with default schema as dbo and table names tab1. then you can differentiate between them saying
select * from DB1.dbo.tab1
OR
select * from DB2.dbo.tab1

Create view across multiple databases

I have two databases; 1 is a live database for daily data input and the other is an archival DB for older data.
How can I create a view which gets data from both databases?
Three tables are involve... database1.dbo.table and database1.dbo.tran1 in same database, and database_archived.dbo.table1:
Create VIEW [dbo].[VW_Table_ALL]
AS
SELECT * FROM database1.dbo.table1
UNION ALL
SELECT * FROM database_archived.dbo.table1 as Data INNER JOIN
database1.dbo.tran1 as Tran ON Data.Tran_id = Tran.Tran_Id
GO
Not sure if you need a UNION or a JOIN, but in either case you can just use a three-part name for the object in the other database:
USE database1;
GO
CREATE VIEW dbo.MyView
AS
SELECT columns FROM dbo.LocalTable
UNION ALL
SELECT columns FROM database2.dbo.RemoteTable;
GO

TSQL: Create a view that accesses multiple databases

I have a special case,
for example in table ta in database A, it stores all the products I buy
table ta(
id,
name,
price
)
in table tb in database B, it contain all the product that people can buy
table tb(
id,
name,
price
....
)
Can I create a view in database A to list all the products that I haven`t bought?
Yes you can - the t-sql syntax is the same as within any other cross database call (within a stored procedure for example).
To reference your tables in the second database you simply need:
[DatabaseName].[Schema].[TableName]
So you would end up with something like
CREATE VIEW [dbo].[YourView]
as
select
a.ID,
a.SomeInfo,
b.SomeOtherInfo
from TableInA a
join DatabaseB.dbo.TableInB b
on -- your join logic goes here
Note that this will only work on the same server - if your databases are on different servers them you will need to create a linked server.
As the other answers indicate, you can use the {LINKED_SERVER.}DATABASE.SCHEMA.OBJECT notation.
You should also be aware that cross-database ownership chaining is disabled by default.
So within a database, granting SELECT on a view allows a user who may not have SELECT on the underlying tables to still SELECT from the view. This may not work across to another database where the user does not have permissions on the underlying table.
Yes, views can reference three part named objects:
create view A.dbo.viewname as
select ... from A.dbo.ta as ta
join B.dbo.tb as tb on ta.id = tb.id
where ...
There will be problems down the road with cross db queries because of backup/restore consistency, referential integrity problems and possibly mirorring failover, but those problems are inherent in having the data split across dbs.

Resources