select * Within an Insert Statement - sql

I'm currently inserting into a table with the following prefix but also manaully set what i want in the last 2 columns ( 1,getdate() )
Insert into [Table1]
select col1,col2,col3, 1,getdate()
from [table2]
Issue is there are loads of columns and causing a mess in the SP.
I've tried to rewrite the statement with...
Insert Into [table1]
Select * from [Table2]
But I also need to take into consideration I want to manually write into those 2 columns..
Is there a way of doing this ?
Many Thanks

This might solve your issue:
Insert into [Table1]
select col1, col2, col3, '1' as [col4] , getdate() as [col5] from [table2]

Two points. First, when using insert you should always be in the habit of naming the columns for the insert:
Insert into [Table1](col1, col2, col3, col4, col5)
select col1, col2, col3, 1, getdate()
from [table2];
Second, you do not have to put getdate() in the insert. Let the database do the work for you with a default value:
create table table1 . . .
col5 date default getdate()
);

Related

INSERT INTO tableName SELECT * INTO tabkeName FROM tableName

How will this below query execute and is there a better way to write this query?
INSERT INTO tableName
SELECT *
INTO tableName
FROM tableName
I would use:
INSERT INTO tableName (col1, col2, col3)
SELECT col1, col2, col3
FROM someOtherTable;
Note that you should generally always explicitly specify which columns you want both for the insert and the select. While your code might run as is, it is prone to breaking should the structure for either table change in the future.

Select rows with same data in columns

I have a SQL Server database with a table with 20 columns. These columns have data as agree or disagree. Now I want to show rows in these columns which have "agree" data in them. I can use where clause but it is a time consuming task for 20 columns. I am looking for a SQL query which does this task.
You can use in:
select t.*
from t
where 'agree' in (col1, col2, ... col20);
There is no shortcut for this type of scenarios, If you want to compare all the columns, you have to explicitly mention each and every column like .
WHERE Col1='agree' AND Col2="agree"....
To avoid coding, you may go with dynamic query creation or creating a function, but ultimately it will be executed as same query comparing all the columns.
What about JOIN ?
If u have such a complex logic, best practices advise to keep data in different tables.
Here's some simplified example code that tests out several methods to return records that may or may not agree.
Just for the fun of it actually.
declare #T table (id int identity(1,1) primary key, col1 varchar(30), col2 varchar(30), col3 varchar(30));
insert into #T (col1, col2, col3) values
('agree','agree','agree'),
('agree','disagree','disagree'),
('agree','disagree',null),
('disagree','disagree','disagree'),
('disagree','disagree',null),
(null,null,null);
select 'OR' as method, * from #T
where (col1='agree' OR col2='agree' OR col3='agree');
select 'AND' as method, * from #T
where (col1='agree' AND col2='agree' AND col3='agree');
select 'IN' as method, * from #T
where 'agree' IN (col1, col2, col3);
select 'NOT IN' as method, * from #T
where 'agree' NOT IN (col1, col2, col3);
select 'LIKE' as method, * from #T
where CONCAT('-',col1,'-',col2,'-',col3,'-') LIKE '%-agree-%';
select 'NOT LIKE' as method, * from #T
where CONCAT('-',col1,'-',col2,'-',col3,'-') NOT LIKE '%-agree-%';
select 'ALL' as method, * from #T
where 'agree' = ALL(select col from (values (col1),(col2),(col3))q(col));
select 'SOME' as method, * from #T
where 'agree' = SOME(select col from (values (col1),(col2),(col3))q(col));
select 'ANY' as method, * from #T
where 'agree' = ANY(select col from (values (col1),(col2),(col3))q(col));
select 'EXISTS' as method, * from #T
where EXISTS (
select 1
from (values (col1),(col2),(col3))q(col)
where col = 'agree'
);
select 'NOT EXISTS' as method, * from #T
where NOT EXISTS (
select 1
from (values (col1),(col2),(col3))q(col)
where col = 'agree'
);

Convert each column of a record into separate record

I have a record:
DECLARE #Tbl AS TABLE(Col1 VARCHAR(10), Col2 VARCHAR(10), Col3 VARCHAR(10));
INSERT INTO #Tbl
VALUES('Val1', 'Val2', 'Val3')
-- Source Record
SELECT Col1, Col2, Col3 FROM #Tbl
Result: Val1 Val2 Val3
I want result of each column as separate two column records like first column will become the title of source column and second column should be the value of source column like the result of below query in which I have achieved the result by UNION ALL :
--Query for Target Result
SELECT 'Col1' AttributeTitle, CONVERT(VARCHAR, Col1) AttributeValue FROM #Tbl
UNION ALL SELECT 'Col2' AttributeTitle, CONVERT(VARCHAR, Col2) AttributeValue FROM #Tbl
UNION ALL SELECT 'Col3' AttributeTitle, CONVERT(VARCHAR, Col3) AttributeValue FROM #Tbl
Problem in this query is I have to explicitly define the columns, is there any way that it should dynamically get the columns names and their values?
You could use UNPIVOT but you still need to know the names of the columns.
SELECT ColumnName, ValueName
FROM (SELECT * FROM #Tbl) AS Data
UNPIVOT
( ValueName
FOR ColumnName IN (Col1, Col2, Col3)
) AS PivottedOutput
I like the apply method for unpivoting in SQL Server:
select v.*
from #tbl t cross apply
(values ('col1', col1),
('col2', col2),
('col3', col3)
) v(AttributeTitle, AttributeValue);
This simplifies the query but it does not directly answer the question.
If you want a variable number of columns, then you are going to have to use dynamic SQL. This is a bit cumbersome on a real table. However, with a table variable or a temporary table, you have the additional issue of scoping rules -- the name of the table will not be in scope when you execute the statement.

How to get count on ths query

I'm doing an
INSERT INTO table1...
SELECT...
FROM table2
However, I need to retrieve the identity from a table3 and do an insert into it just before inserting into table1. These two inserts need to occur together, with table3 insert going first. I've tried something like this:
INSERT INTO table1 (col1, col2, col3)
SELECT (
col1=(insert into table3(col1, col2)values(1,1) select SCOPE_IDENTITY(),
col2, col3)
FROM table2
But that doesn't work. table1.col1 does need the identity value from the new insert into table3. Amount of data to insert probably no more than a few 100 rows. Any suggestions?
It looks like you might be able to use the Output Clause.
BEGIN TRANSACTION
DECLARE #MyResults table(col1 int, col2 int, col3 int);
INSERT INTO table3 (col1, col2)
OUTPUT SCOPE_IDENTITY(), table2.col2, table2.col3 INTO #MyResults
SELECT 1, 1 FROM table2
INSERT INTO table1 (col1, col2, col3)
SELECT col1, col2, col3 FROM #MyResults
COMMIT

Identity Insert Problem

I am trying to run this script:
SET IDENTITY_INSERT dbo.Message ON
INSERT INTO dbo.Message
SELECT (Values I want to insert)
and when I do I still get the error
*An explicit value for the identity column in table 'dbo.Message' can only be specified when a column list is used and IDENTITY_INSERT is ON.*
What am I doing wrong?
The key to your error is "when a column list is used". You want:
SET IDENTITY_INSERT dbo.Message ON
INSERT INTO dbo.Message (column1, column2, ...) -- Added column list here
SELECT (Values I want to insert)
You need to do just as the error message says. Format your code like:
INSERT INTO dbo.Message
(col1, col2, col3, col4)
SELECT Col1, col2, col3, col4
FROM OtherTable
You need the list of fields after the INSERT line, and you need to specify the field names in your SELECT - SELECT * won't work.
You have to mention all the columns Name in both Insert Statement and in select clause.
Some thing like this.
Insert Into tbl
(
[col1],
[col2]
)
SELECT
[col1],
[col2]