Trying to append a query onto a temporary table - sql

Using SQL Server 2008-R2
I have a csv of purchase IDs and in my database there is a table with these purchase IDs and there corresponding User IDs in our system. I need these to run a more complicated query after that using. I tried to bulk insert or run import wizard but I don't have permission. My new idea is to create a #temp using SELECT INTO and then have the query inside that like below.
SELECT *
INTO ##PurchaseIDs
FROM
(
SELECT PurchaseID, UserID, Added
FROM Users
WHERE PurchaseID IN (
/* These are the csv IDs just copied and pasted in */
'49397828',
'49397883',
etc.
What happens is that there are ~55,000 IDs so I get this error.
The query processor ran out of internal resources and could not
produce a query plan. This is a rare event and only expected for
extremely complex queries or queries that reference a very large
number of tables or partitions. Please simplify the query. If you
believe you have received this message in error, contact Customer
Support Services for more information.
It works if I upload about 30,000 so my new plan is to see if I can make a temp table, then append a new table to the end of that. I am also open to other ideas on how to accomplish what I am looking to do. I attached an idea of what I am thinking below.
INSERT *
INTO ##PurchaseIDs
FROM (
SELECT PurchaseID, UserID, Added
FROM Users
WHERE PurchaseID IN (
/* These are the OTHER csv IDS just copied and pasted in */
'57397828',
'57397883',
etc.

You need to create a temp table and insert the values in IN clause to the temp table and Join the temp table to get the result
Create table #PurchaseIDs (PurchaseID int)
insert into #PurchaseIDs (PurchaseID)
Select '57397828'
Union All
Select '57397828'
Union All
......
values from csv
Now use Exists to check the existence of PurchaseID in temp table instead of IN clause
SELECT PurchaseID,
UserID,
Added
FROM Users u
WHERE EXISTS (SELECT 1
FROM #PurchaseIDs p
WHERE u.PurchaseID = p.PurchaseID)

Related

Teradata query using a large list of values in WHERE predicate

I'm attempting to query Teradata in SQL Assistant, something along the lines of
select * from
addressTable
where accountNumber in
(
'AC001',
'AC098',
'AC711',
...
)
from a list of over 100,000 accountNumbers sent to me in a file.
What I have tried
StackOverflow past questions - all seem to say that you need to insert into a temp table using a select clause from a table within the same database
Teradata doco on the link below. When I go to create table globdb.gt1, I get error 'CREATE TABLE Failed 3802: Database 'globdb' does not exist.
https://docs.teradata.com/r/Teradata-Database-SQL-Fundamentals/June-2017/Database-Objects/Tables/Global-Temporary-Tables

Temp table not running

Whenever I run this temp table in google bigquery sql i get "use of create temporary table requires a script"?
CREATE TEMP TABLE products AS
SELECT product, product_color,
FROM `radiant-oven-328313.customer_data.customer_purchase`
WHERE product = "fan";
Does this mean I need to insert data into my table or is my syntax correct??
To insert into my table, I've tried the additional line of code below:
Select product_color as White_color
FROM products
WHERE product_color = "white"
FROM `radiant-oven-328313.customer_data.customer_purchase`
Any help would be much appreciated, thanks!
You will need to specify the name and types for the columns.
For example:
CREATE TEMP TABLE product (product STRING, product_color STRING)
AS
SELECT product, product_color
FROM `radiant-oven-328313.customer_data.customer_purchase`
WHERE product="fan"
;
This will let you create a temporary table and interact with it within your session. However if you are not using this as part of a script already and just need it as part of your SQL Query logic you may want to consider using a CTE or sub-query instead.
For more information on temp tables:
https://cloud.google.com/bigquery/docs/reference/standard-sql/scripting-concepts#temporary_tables
For more information on CTEs:
https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#with_clause

`CREATE TABLE AS SELECT FROM` in Oracle Cloud doesn't create a new table

I was trying to create a series of tables in a single SQL query in Oracle Cloud under the ADMIN account. In the minimum script below, RAW_TABLE refers to an existing table.
CREATE TABLE BASE1 AS SELECT * FROM RAW_TABLE;
CREATE TABLE BASE2 AS SELECT * FROM BASE1;
CREATE TABLE BASE3 AS SELECT * FROM BASE2;
SELECT * FROM BASE3
This returns a view of the first 100 rows in BASE3, but it doesn't create the three tables along the way. Did I miss something or is there something peculiar about create table statements in Oracle SQL?
EDIT: The environment is Oracle Database Actions in Oracle Cloud. The three tables would not be available in the list of tables in the database, and doing something like select * from BASE3 in a subsequent query would fail.
CREATE TABLE BASE1 AS SELECT * FROM RAW_TABLE;
CREATE TABLE BASE2 AS SELECT * FROM BASE1;
CREATE TABLE BASE3 AS SELECT * FROM BASE2;
SELECT * FROM BASE3
Above is a valid query sequence for Oracle database. It should have been created three new tables in database. Since it's not happening please do the work in few steps to find out what's wrong.
First please check whether RAW_TABLE is available in database or not. Then try to select data from RAW_TABLE
select * from RAW_TABLE;
If all those are successful then try to create single table with below query:
CREATE TABLE BASE1 AS SELECT * FROM RAW_TABLE;
Hope you would find the problem by then.
DB-Fiddle:
Creating RAW_TABLE and populating data
create table RAW_TABLE (id int, name varchar(50));
insert into RAW_TABLE values (1,'A');
Query to create three more tables ans selecting from the last table:
CREATE TABLE BASE1 AS SELECT * FROM RAW_TABLE;
CREATE TABLE BASE2 AS SELECT * FROM BASE1;
CREATE TABLE BASE3 AS SELECT * FROM BASE2;
SELECT * FROM BASE3
Output:
ID
NAME
1
A
db<>fiddle here
your query fails because you are executing the whole script as one batch and each line is depends on another one , the transactional DBMS's work with blocks of code as one transaction , and that block of code doesn't commit until sql engine can parse and validate the whole block, and since in your block, BASE1 and BASE2 tables doesn't exists just yet , It fails.
so you need to run each statement as a separate batch. either by executing them one by one or in Oracle you can use / as batch separator, like in sql server you can use GO. these commands are not SQL or Oracle commands and are not sent to the database server , they are just break block of code in batches on your client ( like SQL*Plus or shell or SSMS (for Microsoft sql server), so It would look like this:
CREATE TABLE BASE1 AS SELECT * FROM RAW_TABLE;
/
CREATE TABLE BASE2 AS SELECT * FROM BASE1;
/
CREATE TABLE BASE3 AS SELECT * FROM BASE2;
/
SELECT * FROM BASE3
if your client doesn't support that then you only have to run them one by one in separate batches.

SQL - Split query data stream into 2 separate tables [Theoretical Optimisation]

I am writing some SQL code to be run in MapBasic (MapInfo's Programming language). The best way to describe the question is with an example:
I want to select all records where ShipType="Barge" into a query named Barges and I want all the remaining records to be put in a query OtherShips.
I could simply use the following SQL commands:
select * from ShipsTable where ShipType = "Barge" into Barges
select * from ShipsTable where ShipType <> "Barge" into OtherShips
That's fine and all but I can't help but feel that this is inefficient. Won't SQL be searching through the database twice? Won't it find the rows of data that fit the 2nd Query during the processing of the 1st?
Instead, it would be faster if there was a command like:
select * from ShipsTable where ShipType = "Barge" into Barges ELSE into OtherShips
My question is, can you do this? Is there a command that fits this spec?
Thanks,
You could do this quite easily in SSIS with a conditional split and two different destinations.
But not really in TSQL.
However for "fun" some possibilities are looked at below.
You could create a partitioned view but the requirements that you need to meet for this are quite arduous and the execution plan just loads it all into a spool and then reads the spool twice with two different filters anyway.
CREATE TABLE Barges
(
Id INT,
ShipType VARCHAR(50) NOT NULL CHECK (ShipType = 'Barge'),
PRIMARY KEY (Id, ShipType)
)
CREATE TABLE OtherShips
(
Id INT,
ShipType VARCHAR(50) NOT NULL CHECK (ShipType <> 'Barge'),
PRIMARY KEY (Id, ShipType)
)
CREATE TABLE ShipsTable
(
ShipType VARCHAR(50) NOT NULL
)
go
CREATE VIEW ShipsView
AS
SELECT *
FROM Barges
UNION ALL
SELECT *
FROM OtherShips
GO
INSERT INTO ShipsView(Id, ShipType)
SELECT ROW_NUMBER() OVER(ORDER BY ##SPID), ShipType
FROM ShipsTable
Or you could use the OUTPUT clause and composable DML but that would require inserting both sets of rows into the first table and then cleaning out the unwanted rows afterwards (the second table would only get the correct rows and not need any clean up).
CREATE TABLE Barges2
(
ShipType VARCHAR(50) NOT NULL
)
CREATE TABLE OtherShips2
(
ShipType VARCHAR(50) NOT NULL
)
CREATE TABLE ShipsTable2
(
ShipType VARCHAR(50) NOT NULL
)
INSERT INTO Barges2
SELECT *
FROM
(
INSERT INTO OtherShips2
OUTPUT INSERTED.*
SELECT *
FROM ShipsTable2
) D
WHERE D.ShipType = 'Barge';
DELETE FROM OtherShips2 WHERE ShipType = 'Barge';
MapBasic does provide you access to MapInfo's 'Invert Selection' which would give you anything that wasn't selected from your first query (assuming your first query does return results). You can call it by using it's menu ID (found in Menu.def) which is 311 or if you include menu.def at the top of the file you can reference it through the constant M_QUERY_INVERTSELECT.
eg.
Select * from ShipsTable where ShipType = "Barge" into Barges
Run Menu Command 311
or
Run Menu Command M_QUERY_INVERTSELECT if you have included the menu definitions file.
I believe this would give you better performance than doing a second selection as per your example but you wouldn't be able to then name the results table with an alias without doing another selection. Depends on your use case whether this is worth using or not, for a large query that takes quite a while it could well save on some processing time.

"select * into table" Will it work for inserting data into existing table

I am trying to insert data from one of my existing table into another existing table.
Is it possible to insert data into any existing table using select * into query.
I think it can be done using union but in that case i need to record all data of my existing table into temporary table, then drop that table and finally than apply union to insert all records into same table
eg.
select * into #tblExisting from tblExisting
drop table tblExisting
select * into tblExisting from #tblExisting union tblActualData
Here tblExisting is the table where I actually want to store all data
tblActualData is the table from where data is to be appended to tblExisting.
Is it right method.
Do we have some other alternative ?
You should try
INSERT INTO ExistingTable (Columns,..)
SELECT Columns,...
FROM OtherTable
Have a look at INSERT
and SQL SERVER – Insert Data From One Table to Another Table – INSERT INTO SELECT – SELECT INTO TABLE
No, you cannot use SELECT INTO to insert data into an existing table.
The documentation makes this very clear:
SELECT…INTO creates a new table in the default filegroup and inserts the resulting rows from the query into it.
You generally want to avoid using SELECT INTO in production because it gives you very little control over how the table is created, and can lead to all sorts of nasty locking and other performance problems. You should create schemas explicitly and use INSERT - even for temporary tables.
#Ryan Chase
Can you do this by selecting all columns using *?
Yes!
INSERT INTO yourtable2
SELECT * FROM yourtable1
Update from CTE? http://www.sqlservercentral.com/Forums/Topic629743-338-1.aspx