How to convert a column header and its value into row in sql? - 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;

Related

How to write a SQL query for the below?

I have two tables with n of columns from Col1 to Col30
Table 1.
Templateid Col1 Col2 Col3 Col4 ...
95 2019-05-28 1234 test123 123456
Table 2.
Templateid DisplayName ColumnName
95 date col1
95 rank col2
95 purpose col3
95 sign col4
Expected Results.
Col1Name Col1Value Col2Name Col2Value Col3Name Col3Value ....
date 2019-05-28 rank 1234 purpose test123
This is a crude way of doing it and if you do not know the number of columns in each table you would need to use dynamic sql to enumerate them out but for the purposes of this example I have assumed you do know the number of columns and the names you want to populate.
The union query allows you to pre-populate the desired column names using the col1 syntax, then the pivot allows you to match up the displaynames and the display values. A case statement is required to ensure the correct values are shown and you do need to populate your derived column names for the pivot query but you do get the desired outcome this way.
declare #table1 table (
Templateid int,
Col1 date,
col2 int,
col3 nvarchar(10),
col4 int
);
insert into #table1 (Templateid, col1, col2, col3, col4)
values
(95, '2019-05-28', '1234', 'test123', '123456');
declare #table2 table (
Templateid int,
Displayname nvarchar(10),
ColumnName nvarchar(10)
);
insert into #table2 (Templateid, Displayname, ColumnName)
values
(95, 'date', 'col1'),
(95, 'rank', 'col2'),
(95, 'purpose', 'col3'),
(95, 'sign', 'col4');
select * from
(
select columnname+'Name' as columnname, Displayname
from #table2 t2
union
select columnname+'Value', case when columnname='col1' then cast(col1 as nvarchar(15))
when columnname='col2' then cast(col2 as nvarchar(15))
when columnname='col3' then cast(col3 as nvarchar(15))
when columnname='col4' then cast(col4 as nvarchar(15)) end
from #table1 t1 inner join #table2 t2 on t1.Templateid=t2.Templateid) src
pivot
(max(displayname) for columnname in ([col1Name],[col1Value], [col2Name],[col2Value], [col3Name],[col3Value], [col4Name],[col4Value])) piv;

Change row value to column in SQL

I have table in sql i want to change fieldColumnName as a column and fieldValue as a row.
this is my table image
As per your question, You want to alter table (change column name as well as data type)
ALTER TABLE tablename
CHANGE `fieldColumnName` `column` VARCHAR(255),
CHANGE `fieldValue` `row` VARCHAR(255)
In above query you change datatype as you wish.
If you know all the possible values in the fieldColumnName column then you could use pivot like this:
declare #data table(fieldValue varchar(50), fieldColumnName varchar(50))
INSERT INTO #data
SELECT '1 - value', 'col1'
UNION
SELECT '2 - value', 'col2'
UNION
SELECT NULL, 'col6'
select *
from #data
select col1, col2, col3
from
(
select fieldValue, fieldColumnName
from #data
) d
pivot
(
max(fieldValue)
for fieldColumnName in (col1, col2, col3)
) piv;

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

SQL Server: Select from two tables and insert into one

I have a stored procedure with two table variables (#temp and #temp2).
How can I select the values from both temp tables (Both table variables contain one row) and insert them all in one table ?
I tried the following but this didn't work and I got the error that the number of SELECT and INSERT statements does not match.
DECLARE #temp AS TABLE
(
colA datetime,
colB nvarchar(1000),
colC varchar(50)
)
DECLARE #temp2 AS TABLE
(
colD int
)
...
INSERT INTO MyTable
(
col1,
col2,
col3,
col4
)
SELECT colD FROM #temp2,
colA FROM #temp,
colB FROM #temp,
colC FROM #temp
Many thanks for any help with this, Tim.
As both table variables have a single row you can cross join them.
INSERT INTO MyTable
(col1,
col2,
col3,
col4)
SELECT t.colA,
t.colB,
t.colC,
t2.colD
FROM #temp t
CROSS JOIN #temp2 t2
you should use this if you have only single row in both table #temp and #temp2, because this is a cartesian product.
INSERT INTO MyTable(col1,col2,col3,col4)
SELECT t.colA,
t.colB,
t.colC,
t2.colD
FROM #temp t,#temp2 t2

Grouping result according to one column in sql

I have a sql statement like
SELECT column1, column2,column3, column4 FROM table1 GROUP BY column3
or
SELECT * FROM table1 GROUP BY column3
I want a result which is grouped according to column3 and also has other columns. But it gives an error.What should I do? thanks..
If i understand your expected end result correctly,
try using ORDER instead of GROUP
if however that does not give you your desired output, i apologize.
SELECT column1, column2,column3, column4
FROM table1
ORDER BY column3
SELECT *
FROM table1
ORDER BY column3
What you are trying to do is an undefined behavior. When you specify GROUP BY on a column, there can be multiple values in other columns. There is no sane way for the database to figure out what values to show.
PARTITION is probably what you are looking for. Check this link: http://msdn.microsoft.com/en-us/library/ms189461.aspx
Grouping applies to aggregate functions such as SUM(). It doesn't make sense to group individual fields.
SELECT SUM(col1), MAX(col2), col3 from t1 group by col3
I haven't understood your question exactly and what for you need this query, but maybe you can use this one:
/*t-sql example*/
create table #T (id int identity(1,1), col1 varchar(5), col2 varchar(5), col3 varchar(6))
insert #T (col1,col2,col3) values ('aaa','a1e','group1')
insert #T (col1,col2,col3) values ('bbb','a2e','group1')
insert #T (col1,col2,col3) values ('ccc','a3e','group1')
insert #T (col1,col2,col3) values ('ddd','a4e','group2')
insert #T (col1,col2,col3) values ('eee','a5e','group2')
insert #T (col1,col2,col3) values ('fff','a6e','group3')
select id,col1,col2,#T.col3,subq.cnt from #T
join
(select col3, COUNT(*) as 'cnt' from #T group by col3) as subq
on
#T.col3 = subq.col3
I have used sub-query, but you can use temporary table or WITH. Also, I have used "count" for aggregation just for example.
Max