Create a Table based on a list from another table - sql

I have compiled a list of columns which I hope to build a table with. Is it possible to use a procedure to create a table based on this list? Ie
List
A
B
C
New_Table
Column A Column B Column C

Customer is atable consist of column List with rows:- A, B, C
What I've done is added a RowNum column on run time into the customer table which is dynamic. Due to this another column of row number got attached with List column. Using this:-
RowNum=1 provides A
RowNum=2 provides B
RowNum=3 provides C
Here is the procedure as per your requirement. Please verify:-
create procedure newtable
#tablename NVARCHAR(1000)
as
Declare #col1 varchar(50),#col2 varchar(50),#col3 varchar(50), #cmd NVARCHAR(1000)
select #col1=List from (select List,ROW_NUMBER() Over(Order by List) as RowNum from customer)x where x.RowNum=1
select #col2=List from (select List,ROW_NUMBER() Over(Order by List) as RowNum from customer)x where x.RowNum=2
select #col3=List from (select List,ROW_NUMBER() Over(Order by List) as RowNum from customer)x where x.RowNum=3
set #cmd=N'Create Table '+#tablename+ N' (' + #col1+N' Varchar(50),'+#col2 + N' varchar(50),'+#col3+N' varchar(50))' ;
print #cmd
Exec(#cmd)
After this run your command:-
exec newtable 'New_table'

Related

Select only those columns from a table header which are present in data dictionary ColumnName

Prerequisite : all the tables are dynamic so i cant use the column names
I have two tables
Candidate table :
Table which has all columns and data required to be selected
DataDictionary :
Table where i have only those columns which are to be selected for querying
Now what i want to do is select only that data and columns from the candidate table which are present in datadictionary and skip those that data and column which are not present in datadictionary
what i have tried is
SELECT ColumnName
INTO #Candidate
FROM DataDictionaryDetail WHERE DataDictionaryId =1
select *
from candidate
where NOT EXISTS (select *from #Candidate)
but this brings only columns but not data
I need a proper way to select data also and columns
You need dynamic SQL for this
DECLARE #sql nvarchar(max) = N'
SELECT
'
+ (
SELECT STRING_AGG(QUOTENAME(ColumnName), ',')
FROM DataDictionaryDetail
WHERE DataDictionaryId = 1
) + N'
from candidate;
';
EXEC sp_executesql #sql;

How to add multiple columns from another table in sql server 2017?

I have a requirement where i need to add multiple columns from a source table after checking existence of those columns. for eg:
Table1 containg 7 coulmns like A, B, C, D, E, F, G and Table2 containing 4 columns like A, B, C, D
I want to check the existency of table1 columns in Table2 and if not exists then add rest 3 columns in Table2. I am looking for a solution where i don't need to add these columns manually if not exists in table2.
How can i do this?
I have tried this:
if exists (SELECT TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='table1' and COLUMN_NAME in('A','B','C','D','E','F','G'))
BEGIN
ALTER TABLE table2
ADD [E] FLOAT null
,[F] FLOAT null
,[G] FLOAT null
END;
But this is not the solution of my query I want to make it dynamic and don't know how to do this.
I don't, for one second, think this is a good idea, but this would achieve what you are after. Note that if the same column exists by name in both tables, but have different data types, the column will be ignored:
CREATE TABLE Table1 (a int,
b numeric(12,2),
c datetime2(0),
d date,
e varchar(20),
f sysname,
g varbinary);
CREATE TABLE Table2 (a int,
b numeric(12,2),
c datetime2(0),
d date);
GO
DECLARE #SQL nvarchar(MAX);
SET #SQL = STUFF((SELECT NCHAR(13) + NCHAR(10) +
N'ALTER TABLE Table2 ADD ' + QUOTENAME(T1.name) + N' ' + T1.system_type_name + N';'
FROM sys.dm_exec_describe_first_result_set(N'SELECT * FROM Table1',NULL, NULL) T1
WHERE NOT EXISTS(SELECT 1
FROM sys.dm_exec_describe_first_result_set(N'SELECT * FROM Table2',NULL, NULL) T2
WHERE T1.[name] = T2.[name])
ORDER BY T1.column_ordinal
FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,2,N'');
PRINT #SQL;
EXEC sp_executesql #SQL;
GO
SELECT *
FROM dbo.Table2;
GO
DROP TABLE dbo.Table2;
DROP TABLE dbo.Table1;

How to split a table to a group of tables based on a criteria?

Given a table named "A" contain the following data
Table A:
type name age
-----------------
dog a 2
bird b 1
dog c 3
cat d 2
bird e 2
I am aiming to split this table to a group of tables based on a specific criteria like "Type" to be as follows:
Table 1:
type name age
-----------------
dog a 2
dog c 3
Table 2:
type name age
-----------------
bird b 1
bird e 2
Table 3:
type name age
-----------------
cat d 2
could try using create view
create view table1 as
select type, name, age
from table_a
where type ='dog'
;
create view table2 as
select type, name, age
from table_a
where type ='bird'
;
create view table3 as
select type, name, age
from table_a
where type ='cat '
;
Well assuming the other tables were already created, you would just need an INSERT INTO ... SELECT, e.g. for table1:
INSERT INTO table1 (type, name, age)
SELECT type, name, age
FROM tableA
WHERE type = 'dog';
However, doing what you suggest is a step in the wrong direction, most likely, because your current table would be easier to use. If you instead go with many tables all storing data which is logically very similar, then it will be much harder to do anything.
I think you need to write a procedure with a while loop where iterator will be the count of Types. Then create a table for each type separately with same columns and insert data into the table all within the while loop.
Could you try this whith a cursor and SELECT INTO:
DECLARE #Type VARCHAR(50);
DECLARE #TableCounter INT;
DECLARE #SQL VARCHAR(MAX);
DECLARE #TableName VARCHAR(20);
SET #TableCounter = 1;
DECLARE db_cursor CURSOR FOR
SELECT DISTINCT type
FROM Table_A
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #Type
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT #Type
SET #TableName = CONCAT('Table_', #TableCounter)
SET #SQL = 'SELECT * INTO '+ #TableName +' FROM Table_A WHERE Type = ''' + #Type+''''
EXEC (#SQL)
SET #TableCounter = #TableCounter + 1;
FETCH NEXT FROM db_cursor INTO #Type
END
CLOSE db_cursor
DEALLOCATE db_cursor
I think this code could be short with a nested sentence, but works.
To avoid code duplication and creating unnecessary tables I would create a table-valued UDF (User Defined Function) that takes the criteria as input parameter (type in your case) and returns the original table filtered accordingly:
create function GetNameByType
(
#type varchar(50)
)
returns table
as
return
(
select [type], [name], [age]
from A
where [type] = #type
)
GO
Now you can invoke the function GetNameByType with different type values and you can use it as a table.
Query 1:
select * from GetNameByType('dog')
results for query 1:
query 2:
select * from GetNameByType('bird')
results for query 2:
query 3:
select * from GetNameByType('cat')
results for query 3:
More info on table-valued UDFs can be found here.

SQL Query to match a subset of data

I have a table that looks like:
CLASS VALUE
1 A
1 B
1 C
2 A
2 C
3 B
3 D
4 A
5 C
5 A
I have a user-submitted data-set of values that I want to find any classes whose values are a subset of the user-submitted data-set.
For example,
If data-set was A, B, and C then the results would be class 1, 2, 4, and 5.
If data-set was A and C the results would be class 2, 4, and 5.
If data-set was A, then result would be class 4.
The platform I am on is SQL Server, but really any SQL-based answer would be best.
As per the comment It's passed as a table. - assuming the table is the variable #UserInput with a single column of Value, you can use a WHERE EXISTS clause to check for the existence of that value in the user-input fields, and pull the DISTINCT Class values.
Select Distinct Class
From YourTable T
Where Exists
(
Select *
From #UserInput U
Where T.Value = U.Value
)
Your SQL syntax will vary, but this should point you in the right direction, syntactically.
A full example of how to implement this would be as follows:
Creating the User-defined Table Type
Create Type dbo.UserInput As Table
(
Value Varchar (10)
)
Go
Creating the Stored Procedure
Create Proc dbo.spGetClassesByUserInput
(
#UserInput dbo.UserInput ReadOnly
)
As Begin
Select Distinct Class
From YourTable T
Where Exists
(
Select *
From #UserInput U
Where T.Value = U.Value
)
End
Go
Calling the Stored Procedure with user input
Declare #Input dbo.UserInput
Insert #Input
Values ('A'), ('B'), ('C')
Execute dbo.spGetClassesByUserInput #Input
You can create a stored procedure an pass the user entry as it as string for ex. A,B,C
Create Procedure dbo.GetClasses
#v_UserEntry Varchar(200)
As
Begin
Declare #SQLQuery AS NVarchar(1000)
Declare #ParamDefinition AS NVarchar(300)
SET #v_UserEntry= REPLACE(#v_UserEntry,',',''',N''')
Set #SQLQuery ='Select Class'
Set #SQLQuery = #SQLQuery + ' From TableName'
Set #SQLQuery = #SQLQuery + ' Where Value in (N'''+#v_UserEntry+''')'
Set #SQLQuery = #SQLQuery + ' Group By Class'
Execute sp_executesql #SQLQuery
End
Go

SQL copying record with out specifying column list; ignoring Identity

I'm trying to copy a record from TableA back to TableA, but using a new Identity.
I don't want to specify column list as I have over 100 columns, and there may be more in the future. Id like a chunk of code that can run when/if things change.
After looking similar questions, I have attempted this code
SELECT * INTO #tmp FROM TableA WHERE Id = 1;
ALTER TABLE #tmp DROP COLUMN Id;
INSERT INTO TableA SELECT * FROM #tmp;
Drop Table #tmp;
I am however still getting this error
An explicit value for the identity column in table 'dbo.TableA' can only be specified when a column list is used and IDENTITY_INSERT is ON.
Running a Select * FROM #tmp gives me what I would expect. A single record with all my Columns with the exception of the Id column.
Any Ideas?
Thanks!
EDIT
Here is a pictures of the properties of the Id Column
Use Dynamic SQL: get your list of columns (except ID), build an insert statement using that list, and then call exec on it:
SELECT *
INTO #tmp
FROM TableA
WHERE Id = 1;
ALTER TABLE #tmp DROP COLUMN id;
DECLARE #cols varchar(max);
SELECT
#cols = COALESCE(#cols + ',', '') + COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'TableA' AND COLUMN_NAME <> 'id'
--select #cols -- display column list for debugging
DECLARE #sqltxt varchar(max) = 'INSERT INTO TableA (' + #cols + ') SELECT * FROM #tmp';
--SELECT #sqltxt -- display the statement for debugging
exec (#sqltxt)
DROP TABLE #tmp
Try This
Step 1 :
INSERT INTO Employee1(FirstName,LastName,ManagerID,Salary)
SELECT FirstName,LastName,ManagerID,Salary
FROM Employee1
WHERE EmployeeID=X -- Your Emplyee ID
Step 2:
DELETE FROM Employee1 WHERE EmployeeID=X