CTE in From clause of SQL Query - sql

I need to use CTE query inside from clause of SQL Query
See this example:
Drop Table #Temp
Drop Table #Temp2
Create Table #Temp(name1 text, name2 text)
Insert INTO #Temp Values ('test','test')
Insert INTO #Temp Values ('test','test')
select * into #Temp2
from #Temp
Select * from #Temp2
Here, I am just inserting rows into temp table 'Temp2' from selecting records from Temp... this is working fine...
But my need is, have to use CTE inside from clause.. like
select * into #Temp2
from (;With CTE as ( Select * from #Temp) select * from CTE)
Please don't encourage me to separate CTE query..because, I can't control that part of query since it is being provided by other system.
select * into #Temp2
from ("Query Provided by Other System")
So the "Query Provided by Other System" may or may not be the CTE query.

Check with below syntax, its worked for me and i hope you are looking for same:
With CTE as ( Select * from #Temp)
select * into #Temp2 from CTE

use below query
Create Table #Temp(name1 text, name2 text)
Insert INTO #Temp Values ('test','test')
Insert INTO #Temp Values ('test','test')
GO
With CTE as ( Select * from #Temp)
select * into #Temp2 from CTE
select * from #Temp2
GO
Drop Table #Temp
Drop Table #Temp2

Related

Create table in SQL Server using union

In mysql we write query as
create table new_table as (select a.* from Table1 a union select b.* from Table2 b)
This syntax doesn't work in SQL Server - what's the way around for creating a table from union in SQL Server?
in SQL Server, you can use SELECT .. INTO
select a.*
into new_table
from Table1 a
union
select b.*
from Table2 b
The following query should do what you want:
select * into new_table
from (
select * from Table1 union select * from Table2 ) a
You need to write your query as shown below for creating table in sql server using union clause.
create table #table1 (Id int, EmpName varchar(50))
insert into #table1 values (1, 'Suraj Kumar')
create table #table2 (Id int, EmpName varchar(50))
insert into #table2 values (2, 'Davinder Kumar')
SELECT * INTO #NewTable FROM
(SELECT Id, EmpName FROM #table1
UNION
SELECT Id, EmpName FROM #table2
)a
SELECT * FROM #NewTable
Here new table of name - #NewTable has been created by union of two tables #table1 and #table2

Inserting temp table values into a table.

I have a temp table declared
declare #tmptable(
value nvarchar(500) not null
);
I use a function to insert values into that temp table.
I am trying to figure out how to update a table using the values of #tmptable
insert into t1 (
active
,SchoolId
,inserted
)
select
1
,temp.value
,#insertedDate
select temp.value from #tmptable;
When i try to insert in table t1 it doesn't work. I guess there are two Select statements is causing the problem. Please let me know how to fix it. Thanks
Try this one -
INSERT INTO dbo.t1
(
Active
, SchoolId
, Inserted
)
SELECT
1
, t.value
, #insertedDate
FROM #tmptable t;
INSERT INTO t1
(
ACTIVE
,SchoolId
,INSERTED
)
SELECT 1
,temp.value
,#insertedDate
FROM #tmptable temp;
insert into t1 (
active
,SchoolId
,inserted
)
select
1
,temp.value
,#insertedDate
from #tmptable;
this will work...

Union temporary tables to a final temporary table

I have like 10 diff temporary tables created in SQL server, what I am looking to do is union them all to a final temporary table holding them all on one table. All the tables have only one row and look pretty much exactly like the two temp tables below.
Here is what I have so far this is an example of just two of the temp tables as their all exactly like this one then #final is the table I want to union the all to:
create table #lo
(
mnbr bigint
)
insert into #login (mnbr)
select distinct (_ID)
FROM [KDB].[am_LOGS].[dbo].[_LOG]
WHERE time >= '2012-7-26 9:00:00
Select count(*) as countreject
from #lo
create table #pffblo
(
mber_br
)
insert into #pffblo (mber_br)
select distinct (mber_br)
from individ ip with (nolock)
join memb mp with (nolock)
on( ip.i_id=mp.i_id and mp.p_type=101)
where ip.times >= '2012-9-26 11:00:00.000'
select count(*) as countaccept
create table #final
(
countreject bigint
, Countacceptbigint
.....
)
insert into #final (Countreject, Countaccept....more rows here...)
select Countreject, Countaccept, ...more rows selected from temp tables.
from #final
union
(select * from #lo)
union
(select * from #pffblo)
select *
from #final
drop table #lo
drop table #pffblo
drop table #final
if this the form to union the rows form those temp tables to this final one. Then is this correct way to show all those rows that were thus unioned. When I do this union I get message number of columns in union need to match number of columns selected in union
I think you're using a union the wrong way. A union is used when you have to datasets that are the same structure and you want to put them into one dataset.
e.g.:
CREATE TABLE #Table1
(
col1 BIGINT
)
CREATE TABLE #Table2
(
col1 BIGINT
)
--populate the temporary tables
CREATE TABLE #Final
(
col1 BIGINT
)
INSERT INTO #Final (col1)
SELECT *
FROM #Table1
UNION
SELECT *
FROM #Table2
drop table #table1
drop table #table2
drop table #Final
I think what you're trying to do is get 1 data set with the count of all your tables in it. Union won't do this.
The easiest way (although not very performant) would be to do select statements like the following:
CREATE TABLE #Table1
(
col1 BIGINT
)
CREATE TABLE #Table2
(
col1 BIGINT
)
--populate the temporary tables
CREATE TABLE #Final
(
col1 BIGINT,
col2 BIGINT
)
INSERT INTO #Final (col1, col2)
select (SELECT Count(*) FROM #Table1) as a, (SELECT Count(*) FROM #Table2) as b
select * From #Final
drop table #table1
drop table #table2
drop table #Final
It appears that you want to take the values from each of temp tables and then place then into a single row of data. This is basically a PIVOT, you can use something like this:
create table #final
(
countreject bigint
, Countaccept bigint
.....
)
insert into #final (Countreject, Countaccept....more rows here...)
select
from
(
select count(*) value, 'Countreject' col -- your UNION ALL's here
from #lo
union all
select count(*) value, 'countaccept' col
from #pffblo
) x
pivot
(
max(value)
for col in ([Countreject], [countaccept])
) p
Explanation:
You will create a subquery similar to this that will contain the COUNT for each of your individual temp table. There are two columns in the subquery, one column contains the count(*) from the table and the other column is the name of the alias:
select count(*) value, 'Countreject' col
from #lo
union all
select count(*) value, 'countaccept' col
from #pffblo
You then PIVOT these values to insert into your final temp table.
If you do not want to use PIVOT, then you can use a CASE statement with an aggregate function:
insert into #final (Countreject, Countaccept....more rows here...)
select max(case when col = 'Countreject' then value end) Countreject,
max(case when col = 'countaccept' then value end) countaccept
from
(
select count(*) value, 'Countreject' col -- your UNION ALL's here
from #lo
union all
select count(*) value, 'countaccept' col
from #pffblo
) x
Or you might be able to JOIN all of the temp tables similar to this, where you create a row_number() for the one record in the table and then you join the tables with the row_number():
insert into #final (Countreject, Countaccept....more rows here...)
select isnull(lo.Countreject, 0) Countreject,
isnull(pffblo.Countaccept, 0) Countaccept
from
(
select count(*) Countreject,
row_number() over(order by (SELECT 0)) rn
from #lo
) lo
left join
(
select count(*) Countaccept,
row_number() over(order by (SELECT 0)) rn
from #pffblo
) pffblo
on lo.rn = pffblo.rn
SELECT *
INTO #1
FROM TABLE2
UNION
SELECT *
FROM TABLE3
UNION
SELECT *
FROM TABLE4
If you would like to get count for each temporary table in the resulting table, you will need just to calculate it for each column in subquery:
INSERT INTO result (col1, col2,...
SELECT
(SELECT COUNT() FROM tbl1) col1
,(SELECT COUNT() FROM tbl2) col2
..

Inserting data into a temporary table

After having created a temporary table and declaring the data types like so;
CREATE TABLE #TempTable(
ID int,
Date datetime,
Name char(20))
How do I then insert the relevant data which is already held on a physical table within the database?
INSERT INTO #TempTable (ID, Date, Name)
SELECT id, date, name
FROM physical_table
To insert all data from all columns, just use this:
SELECT * INTO #TempTable
FROM OriginalTable
Don't forget to DROP the temporary table after you have finished with it and before you try creating it again:
DROP TABLE #TempTable
SELECT ID , Date , Name into #temp from [TableName]
My way of Insert in SQL Server. Also I usually check if a temporary table exists.
IF OBJECT_ID('tempdb..#MyTable') IS NOT NULL DROP Table #MyTable
SELECT b.Val as 'bVals'
INTO #MyTable
FROM OtherTable as b
SELECT *
INTO #TempTable
FROM table
I have provided two approaches to solve the same issue,
Solution 1: This approach includes 2 steps, first create a temporary table with
specified data type, next insert the value from the existing data
table.
CREATE TABLE #TempStudent(tempID int, tempName varchar(MAX) )
INSERT INTO #TempStudent(tempID, tempName) SELECT id, studName FROM students where id =1
SELECT * FROM #TempStudent
Solution 2: This approach is simple, where you can directly insert the values to
temporary table, where automatically the system take care of creating
the temp table with the same data type of original table.
SELECT id, studName INTO #TempStudent FROM students where id =1
SELECT * FROM #TempStudent
After you create the temp table you would just do a normal INSERT INTO () SELECT FROM
INSERT INTO #TempTable (id, Date, Name)
SELECT t.id, t.Date, t.Name
FROM yourTable t
The right query:
drop table #tmp_table
select new_acc_no, count(new_acc_no) as count1
into #tmp_table
from table
where unit_id = '0007'
group by unit_id, new_acc_no
having count(new_acc_no) > 1
insert into #temptable (col1, col2, col3)
select col1, col2, col3 from othertable
Note that this is considered poor practice:
insert into #temptable
select col1, col2, col3 from othertable
If the definition of the temp table were to change, the code could fail at runtime.
Basic operation of Temporary table is given below, modify and use as per your requirements,
-- CREATE A TEMP TABLE
CREATE TABLE #MyTempEmployeeTable(tempUserID varchar(MAX), tempUserName varchar(MAX) )
-- INSERT VALUE INTO A TEMP TABLE
INSERT INTO #MyTempEmployeeTable(tempUserID,tempUserName) SELECT userid,username FROM users where userid =21
-- QUERY A TEMP TABLE [This will work only in same session/Instance, not in other user session instance]
SELECT * FROM #MyTempEmployeeTable
-- DELETE VALUE IN TEMP TABLE
DELETE FROM #MyTempEmployeeTable
-- DROP A TEMP TABLE
DROP TABLE #MyTempEmployeeTable
INSERT INTO #TempTable(ID, Date, Name)
SELECT OtherID, OtherDate, OtherName FROM PhysicalTable
insert #temptable
select idfield, datefield, namefield from yourrealtable
All the above mentioned answers will almost fullfill the purpose. However, You need to drop the temp table after all the operation on it. You can follow-
INSERT INTO #TempTable (ID, Date, Name)
SELECT id, date, name
FROM physical_table;
IF OBJECT_ID('tempdb.dbo.#TempTable') IS NOT NULL
DROP TABLE #TempTable;

Why No Error in T-SQL?

When the following SQL is run you don't get an error in either SQL version 2005 or 2008 R2.
select 1 as MyVal, 'string' as MyText
into #table1
select 1 as thisColumnDoesntExistInTable1, 'string' as MyText
into #table2
select * from #table1
select * from #table2
-- WHY NO ERROR HERE ---
select *
from #table2
where thisColumnDoesntExistInTable1 in
(
select thisColumnDoesntExistInTable1 from #table1
)
drop table #table1
drop table #table2
But if you change the statement as follows by adding an alias to the inner select...
select *
from #table2
where thisColumnDoesntExistInTable1 in
(
select a.thisColumnDoesntExistInTable1 from #table1 a
)
...you do get an error.
Effectively, you have this. So no error
select * from #table2 t2
where thisColumnDoesntExistInTable1 in
(select t2.thisColumnDoesntExistInTable1 from #table1 )
When you qualify this to be explicit for table1, you get the error
The scope of the query is available in the subselect. You can see this more clearly if you change what's in #table2.
select 1 as MyVal, 'string' as MyText
into #table1
select 2 as thisColumnDoesntExistInTable1, 'string' as MyText
into #table2
select * from #table1
select * from #table2
select * from #table2 where thisColumnDoesntExistInTable1 in (select thisColumnDoesntExistInTable1 from #table1 )
drop table #table1
drop table #table2
So you can see, the result will show 2 instead of 1 because you're accessing the value of thisColumnDoesntExistInTable1 from #table2.
Column thisColumnDoesntExistInTable1 does not, as it says, exist in #table1. In the first query, when the compiler hits the subquery, since the column is not aliased it looks in all tables involved in the query, finds it in one, and uses it from there. In the second query, the column is aliased, so SQL only checks the referenced table for the column, doesn't find it, and throws the error.