How to display the all records of table as columns in sql query? - sql

I have a table with 200 records so i need to show all 200 rows as 200 columns it is not possible to write all 200 records in pivot IN() section as when i insert 201st record in table its column should also to be shown.
select * from Table_Name
Returns 200 rows
so i need to show 200 columns in other queries
SELECT * FROM
(
select RecordName from Table_Name
) AS T
PIVOT (Max(RecordName) FOR MiscMasterName IN (Record1,Record2)) AS T2
gives 2 columns
like wise i need 200 columns such that if i add 201st records
and wherever i execute the query i get 201 columns after inserting new record....

You need to do a dynamic pivot. Something like this:
Test data:
CREATE TABLE Table_Name(MiscMasterName VARCHAR(200),RecordName VARCHAR(200))
INSERT INTO Table_Name
VALUES
('Record1','aValue'),
('Record2','SomeValue')
Finding the columns
DECLARE #cols VARCHAR(MAX)
SET #cols=STUFF
(
(
SELECT
',' +QUOTENAME(MiscMasterName)
FROM
Table_Name
FOR XML PATH('')
)
,1,1,'')
Declare and executing dynamic sql
DECLARE #query NVARCHAR(4000)=
N'SELECT
*
FROM
(
SELECT
RecordName,
MiscMasterName
from
Table_Name
) AS T
PIVOT (Max(RecordName) FOR MiscMasterName IN ('+#cols+')) AS T2'
EXECUTE(#query)
Cleaning up after myself
DROP TABLE Table_Name
Output
Record1 Record2
aValue SomeValue

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 interrogate multiple tables with different structure?

I am using Sql-Server 2016 in a C# application.
Let's say I have two tables:
CREATE TABLE Table_A
(
UserID NVARCHAR2(15),
FullName NVARCHAR2(25),
Available NUMBER(1),
MachineID NVARCHAR2(20),
myDate date
);
and
CREATE TABLE Table_B
(
UserID NVARCHAR2(15),
FullName NVARCHAR2(25),
Team NVARCHAR2(15),
MachineID NVARCHAR2(20),
Stuff NUMBER(2)
);
I want to perform a global select so that I will get as result data from both tables, somehow concatenated and of course, when a column does not exist in one of the tables, that column to be automatically populated with NULL, and if a column exists on both tables the results must be merged in a single column.
The first solution that pops-up is a UNION with NULL aliases for the missing columns, sure. The problem is that at runtime I will not be able to know in advance which tables are interrogated so that I could anticipate the column names. I need a more general solution.
The expected result from the two tables must look like this:
user_Table_A; fullName_Table_A; 1; machineID_Table_A; 12-JUN-18; NULL; 10;
user_Table_B; fullName_Table_B; NULL; machineID_Table_B; NULL; team_Table_B; 20;
The data for the two tables is inserted with the following commands:
INSERT INTO Table_A VALUES ('user_Table_A', 'fullName_Table_A', 1, 'machineID_Table_A', TO_DATE('12-06-2018', 'DD-MM-YYYY'));
INSERT INTO Table_B VALUES ('user_Table_B', 'fullName_Table_B', 'team_Table_B', 'machineID_Table_B', 20);
You can do something like this. I havent have time to completely tweak it, so there can be something the order of the columns. But perhaps it can get you started:
You also write that you use Oracle - Im not sure what you wanted, but this is in pure sql-server version.
SQL:
IF OBJECT_ID('tempdb..#temp') IS NOT NULL
/*Then it exists*/
DROP TABLE #temp;
GO
DECLARE #SQLList nvarchar(max)
DECLARE #SQLList2 nvarchar(max)
DECLARE #SQL nvarchar(max)
with table_a as (
select column_name as Table_aColumnName,ORDINAL_POSITION from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'table_a'
)
,
table_b as (
select column_name as Table_bColumnName,ORDINAL_POSITION from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'table_b'
)
,preresult as (
select case when Table_aColumnName IS null then 'NULL as ' + Table_bColumnName else Table_aColumnName end as Table_a_ColumnName,case when Table_bColumnName IS null then 'NULL as ' +Table_aColumnName else Table_bColumnName end as Table_b_ColumnName
,a.ORDINAL_POSITION,b.ORDINAL_POSITION as Table_b_Ordinal from table_a a full join Table_B b on a.Table_aColumnName = b.Table_bColumnName
)
select * into #temp from preresult
SET #SQLList = (
select distinct display = STUFF((select ','+table_a_columnName from #temp b order by table_b_ordinal FOR XML PATH('')),1,1,'') from #temp a
)
SET #SQLList2 = (
select distinct display = STUFF((select ','+table_b_columnName from #temp b order by Table_b_Ordinal FOR XML PATH('')),1,1,'') from #temp a
)
SET #SQL = 'select ' +#SQLList +' from dbo.Table_a union all select ' + #SQLList2 + ' from dbo.table_b'
exec(#SQL)
Result:

Dynamic SQL - union all tables (number of tables is dynamically created)

I don't know how to union all tables with dynamic SQL.
The issue is that I'm inserting into db a number of tables - all having the same structure (only one varchar column
[Line]
). I don't know that would be the number of tables inserted - it depends on the project. But I want to automate the process in SQL.
I'm using this query to find those tables, additionally I'm adding some [RowNum] that may serve as an ID of each table:
SELECT
ROW_NUMBER() OVER (ORDER BY Name) AS [RowNum],
[Name] AS [Name]
INTO #all_tables_with_ids
FROM #all_tables
This query returns:
RowNum | Name
------------------------
1 | Table 1
2 | Table 2
3 | Table 3
4 | Table 4
I would like to merge all tables together. I was trying to write some insert into in while loop but it didn't work. I figured out that I need dynamic SQL.
Can you suggest something? I was trying to find some examples but all of them fail due to the fact that the list of tables is not known at the beginning, so it needs to be created dynamically as well.
Demo here:
create table #test
(
RowNum int,
Name varchar(100)
)
insert into #test
select 1,quotename('table1')
union all
select 2,quotename('table2')
declare #sql nvarchar(max)
set #sql='select somecol from tbl union all '
declare #sql1 nvarchar(max)
;with cte
as
(select #sql as ql,name,rplc
from
#test t1
cross apply
(select replace(#sql,'tbl',name) as rplc from #test t2 where t1.rownum=t2.rownum)b
)
select #sql1= stuff(
(select ''+rplc
from cte
for xml path('')
),1,0,'')
set #sql1=substring(#sql1,1,len(#sql1)-10)
print #sql1
--exec(#Sql1)

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

TSQL Subquery for Column Names?

Is it possible to use a set of query results for column names in a select statement?
Example, I have a table named TableA:
Column: Type:
KeyOne nvarchar(5)
KeyTwo nvarchar(5)
TableB is another table, whose column names might be stored in TableA.
Suppose TableB is like this:
Column: Type:
Val1 int
Val2 int
Is there any way I could do a query like this to get the columns?
SELECT (select TOP 1 KeyOne, KeyTwo FROM TableA)
FROM TableB
Another example using strings would be like this:
SELECT (select 'Val1', 'Val2')
FROM TableB
Is this possible in any way without concatenated SQL?
Unfortunately you can only do this with dynamic SQL, but it's pretty straightforward:
DECLARE #cols VARCHAR(MAX) = (SELECT TOP 1 KeyOne+','+KeyTwo FROM TableA)
,#sql VARCHAR(MAX)
SET #sql = 'SELECT '+#cols+' FROM TableB'
EXEC (#sql)
You can read table column names dynamically from sys.columns system views or using other management views
select name from sys.columns where object_id = object_id(N'TableName')
Then by creating a dynamic SQL query you can create your own select