Get ID of inserted & Selected row after multiple insert [duplicate] - sql

This question already has answers here:
Insert Into... Merge... Select (SQL Server)
(1 answer)
Combine OUTPUT inserted.id with value from selected row
(2 answers)
Closed 4 years ago.
I have a query running in loop which I am trying to optimize as this
INSERT INTO myTable (col1, col2, col3)
OUTPUT inserted.id, SOURCE_ROW_ID_NEEDED_HERE
SELECT col1, col2, col3
FROM myTable
WHERE col2 = 20 --any value
My problem is : col2 = 20 can have N number of rows which get inserted, I need the id of the source row for the new record. For example say there are 3 rows for col2 = 20 and id of them are 11,12,15. The new inserted ID are say 150,151,152.
I would need
11 150
12 151
15 152

Are you looking for something like
CREATE TABLE T1(
Col1 INT IDENTITY(1, 1),
Col2 INT,
Col3 INT
);
CREATE TABLE T2(
Col1 INT IDENTITY(1, 1),
Col2 INT,
Col3 INT
);
INSERT INTO T2(Col2, Col3) VALUES
(11, 150),
(12, 151),
(15, 152);
DECLARE #TT TABLE (ID INT, Col2 INT);
SET IDENTITY_INSERT T1 ON;
INSERT INTO T1 (Col1, Col2, Col3)
OUTPUT INSERTED.Col1,
INSERTED.Col2
INTO #TT (ID, Col2)
SELECT Col1,
Col2,
Col3
FROM T2;
SELECT *
FROM #TT;
SET IDENTITY_INSERT T1 OFF;
Demo

Related

Arrange NULL at the end in each column of the table

I have a table that contains two columns col1, col2.
NULL need to be placed at the end of each column.
Data in my table now.
--- ---
col1 col2
--- ---
1 null
2 2
3 null
4 4
null 5
create table mytable (
col1 number(3),
col2 number(3)
);
insert into mytable values(1, null);
insert into mytable values(2, 2);
insert into mytable values(3, null);
insert into mytable values(4, 4);
insert into mytable values(null, 5);
I need to update them in this format.
--- ---
col1 col2
--- ---
1 2
2 4
3 5
4 null
This mostly solves the problem; you'll need to put the final update in a recursive trigger so it executes the proper number of times.
-- remove nulls from col2
delete from mytable where col2 is null;
-- erase col1
update mytable
set col1 = null;
-- add "footer" row
insert into mytable (col1,col2) values ((select count(*)+1 from mytable), null);
-- update col1 for 1 remaining record
update mytable
set col1 = (select count(*) from mytable where col1 is not null)
where col2 = (select min(col2) from mytable where col1 is null);

Adding result of column expression as new column on table variable creation

I'm sure this is really easy but I can't think of a solution and can't seem to find any documentation that answers my exact question.
While inserting values into a table variable how do I set the value of a field to be the result of an expression from another field in the same table?
For example:
declare #tableVar table(
[col1] int,
[col2] dec(18,2),
[col3] dec(18,2)
)
insert into #tableVar
values (100,.03,[col1] * [col2])
select *
from #tableVar
Would ideally return:
col1 col2 col3
100 0.03 3.00
But I get this error instead:
Msg 207, Level 16, State 1, Line 19
Invalid column name 'col1'.
Msg 207, Level 16, State 1, Line 19
Invalid column name 'col2'.
I understand why I get the error I just can't seem to come up with a solution.
Any hints?
You would use a subquery:
insert into #tableVar (col1, col2, col3)
select col1, col2, col1 * col2
from (values (100, 0.03)) v(col1, col2);
Or, better yet, use a computed column:
declare #tableVar table (
col1 int,
col2 dec(18, 2),
col3 as ( convert(dec(18, 2), col1 * col2) )
);
insert into #tableVar (col1, col2)
values (100, 0.03);
Note that both these examples explicitly list the columns being inserted. That is considered a best-practice.
You need values construct :
insert into #tableVar (col1, col2, col3)
select col1, col2, col1 * col2
from (values (100, .03)
) t(col1, col2);

How to split 4 columns, one row into 2 columns, two rows?

I am using SSRS 2008R2 and SSMS 2008R2 and I am trying to split 4 columns, one row into two rows, 2 columns. How can I do this?
Here is some sample data:
create table #foo
(col1 int, col2 int, col3 int, col4 int)
insert #foo values(1,2,3,4)
insert #foo values(5,6,7,8)
insert #foo values(9,10,11,12)
select * from #foo
But I want to transform this data to look like this:
create table #goo (col1 int, col2 int)
insert #goo values(1,2)
insert #goo values(3,4)
insert #goo values(5,6)
insert #goo values(7,8)
insert #goo values(9,10)
insert #goo values(11,12)
select * from #goo
How can I do this?
As simple as:
create table #foo(col1 int, col2 int, col3 int, col4 int);
insert #foo values(1,2,3,4),(5,6,7,8),(9,10,11,12);
SELECT col1, col2
FROM #foo
UNION ALL
SELECT col3, col4
FROM #foo;
LiveDemo
First 2 columns UNION ALL with 3rd and 4th columns.
If you need to store in #goo use:
SELECT col1, col2
INTO #goo
FROM #foo
UNION ALL
SELECT col3, col4
FROM #foo;
SELECT * FROM #goo;
I imagine it would look something like this
SELECT CONCAT_WS(" ", col1, col2) FROM #foo UNION ALL
SELECT CONCAT_WS(" ", col3, col4) FROM #foo;
Breakdown
concat_ws - Combines two columns with a word separator. In this case a space.
Union All - Merges with another selector to create multiple rows.
SQLFiddle
http://sqlfiddle.com/#!9/ca24df/3/0

How to convert a column header and its value into row in sql?

I have a table with columns say col1, col2, col3. The table has many rows in it.
Let's assume val1, val2, val3 is one such row. I want to get the result as
Col1, Val1
Col2, Val2
Col3, Val3
That is 3 rows - one for each column and its value.
I am using SQL Server 2008. I read about pivots. Are pivots a way to solve this problem? Can someone route me to some examples or solutions how to solve this problem?
Thanks a lot
Maybe something like this:
Test data
DECLARE #T TABLE(Col1 INT, Col2 INT, Col3 INT)
INSERT INTO #T
VALUES (1,1,1)
Query
SELECT
*
FROM
(
SELECT
t.Col1,
t.Col2,
t.Col3
FROM
#T AS t
) AS SourceTable
UNPIVOT
(
Value FOR Col IN
(Col1,Col2,Col3)
) AS unpvt
Output
1 Col1
1 Col2
1 Col3
To do this kind of thing read the following: Using PIVOT and UNPIVOT
Pivot function allow you to convert row values in from of column..
Also check : Dynamic Pivoting in SQL Server
Example :
create table #temptable(colorname varchar(25),Hexa varchar(7),rgb varchar(1), rgbvalue tinyint)
GO
insert into #temptable values('Violet','#8B00FF','r',139);
insert into #temptable values('Violet','#8B00FF','g',0);
insert into #temptable values('Violet','#8B00FF','b',255);
insert into #temptable values('Indigo','#4B0082','r',75);
insert into #temptable values('Indigo','#4B0082','g',0);
insert into #temptable values('Indigo','#4B0082','b',130);
insert into #temptable values('Blue','#0000FF','r',0);
insert into #temptable values('Blue','#0000FF','g',0);
insert into #temptable values('Blue','#0000FF','b',255);
SELECT colorname,hexa,[r], [g], [b]
FROM
(SELECT colorname,hexa,rgb,rgbvalue
FROM #temptable) AS TableToBePivoted
PIVOT
(
sum(rgbvalue)
FOR rgb IN ([r], [g], [b])
) AS PivotedTable;
Create a temproary table:
CREATE TABLE #table2
(
name NCHAR,
bonus INT
)
Now Select and execute the below statement if there is an empty.
SELECT * FROM #table2
INSERT INTO #table2 (name,bonus) VALUES ('A',10)
INSERT INTO #table2 (name,bonus) VALUES ('B',20)
INSERT INTO #table2 (name,bonus) VALUES ('C',30)
After insert the values into table. select and execute the below line if you get records:
SELECT * FROM #table2
Input:
name bonus
A 10
B 20
C 30
Change the input into like this result
Result:
Cost A B C
Bonus 10 20 30
By using this code:
SELECT 'Bonus' AS Cost,
[A],[B],[C]
FROM
(SELECT name, Bonus
FROM #table2) AS TempTbl
PIVOT
(
AVG(bonus)
FOR [name] IN ([A],[B],[C])
) AS PivotTable;

Merge with same target and source table

I have one table where I want to check if record exists leave it alone, if not insert new row and update previous row. I am wondering if I can use merge here like below ?
CREATE TABLE a
(keycol INT PRIMARY KEY,
col1 INT NOT NULL,
col2 INT NOT NULL,
col3 INT NOT NULL);
INSERT INTO a VALUES (1,0,0,0),(2,0,0,0);
MERGE INTO a
USING select 1 from a where col1 = 3
WHEN NOT MATCHED THEN
UPDATE SET
col2 = 2,
col2 = 2,
col3 = 2
where col1 = 3
WHEN NOT MATCHED THEN
INSERT (keycol, col1, col2, col3)
VALUES (4, 0, 0, 0)
Thanks,
MERGE INTO a
USING (
VALUES (3,3,2,2),
(4,0,0,0)
) AS source (keycol, col1, col2, col3)
ON a.keycol = source.keycol
AND a.col1 = source.col1
WHEN MATCHED THEN
UPDATE
SET col2 = source.col2,
col3 = source.col3
WHEN NOT MATCHED THEN
INSERT (keycol, col1, col2, col3)
VALUES (keycol, col1, col2, col3);