I have a scenario where I need to convert column to rows. I have two tables table1 and table2 with the following structure
Table1:
Col11 Col12 Col13
-------------------------
200 text 55
Table2:
Col1 Col2
--------------------
Col11
Col12
Col13
In need the following result from the above two tables
Col1 Col2
--------------------
Col11 200
Col12 text
Col13 55
Is it possible to do this by using temp tables ?
You can do it using UNION ALL:
SELECT 'Col1' AS Col1, Col1 AS Col2
FROM mytable
UNION ALL
SELECT 'Col2', Col2
FROM mytable
UNION ALL
SELECT 'Col3', Col3
FROM mytable
Table2 doesn't seem to play any role in producing the required result set. So it is left out in the above query.
you can use cross apply or UNPIVOT to get
select
coll,colvalue
from PivotColToRow
cross apply
(
select 'col1', col1 union all
select 'col2', col2 union all
select 'col3', col3
) c (Coll, colvalue);
Using UNPIVOT
select col,colvalue
from PivotColToRow
unpivot
(
colvalue
for col in (col1, col2, col3)
) unpiv;
try this
Related
This is similar to the code I use:
SELECT id, col1 FROM table1
UNION ALL
SELECT id, col2 FROM table2
UNION ALL
SELECT id, col3 FROM table3
...
For example col2 in table2 does not exist, how to make this query work and not to query for columns that do not exist?
Using NULL or any other value and alias it to match column list defintion:
SELECT id, col1 FROM table1
UNION ALL
SELECT id, NULL AS col2 FROM table2
UNION ALL
SELECT id, col3 FROM table3
I understand how to display the 5 most occurring value of a column like so:
select top 5 col1, count(col1)
from table1
group by col1
order by count(col1) desc;
However, how do I create a query that displays all other values of the same column that are not in the result of the above query?
I tried the following sub query:
select col1
from table1
where col1 not in
(select top 5 col1, count(col1)
from table1
group by col1
order by count(col1) desc);
However the query failed and I got the following error message:
Only one expression can be specified in the select list when the
subquery is not introduced with EXISTS.
For Sql Server 2012+ you can use offset:
select col1, count(col1)
from table1
group by col1
order by count(col1) desc
offset 5 rows
You may want to add tiebreaker to your ordering here to make it deterministic:
select col1, count(col1)
from table1
group by col1
order by count(col1) desc, col1
offset 5 rows
Problem is you cannot select more than one column inside subquery.
(select top 5 col1, count(col1)..
You can remove the count(col1) from subquery but NOT IN clause can fail when col1 in subquery has NULL values
Try changing like this
with cte as
(
select top 5 col1
from table1
group by col1
order by count(col1) desc
)
select * from table1 A
where not exists (select 1 from cte B where a.Col=b.col)
Use OFFSET
select col1, count(col1)
from table1
group by col1
order by count(col1) desc
OFFSET 5 ROWS -- skip 5 rows, must use with order by
I want to INSERT INTO by more than one value at a time, I did this by doing the following:
INSERT INTO table_1(col_1,col_2,col_3)
SELECT col_1, col2, (SELECT col3 FROM table_3)
FROM table_2
But col3 from table_3 is a datetime format, while col3 from table_1 needs an integer value. I did this by doing the following:
CAST(CONVERT(varchar(10),(SELECT col3 FROM table_3),112)AS int)
When I run this I get a more than one result in a subquery error. I have really no idea whatsoever on how to fix this. Hopefully you do.
Thank you in advance.
INSERT INTO table_1(col_1,col_2,col_3)
SELECT col_1, col2, (CAST(CONVERT(varchar(10),(SELECT top 1 col3 FROM table_3),112)AS int))
FROM table_2
You need to use top 1 to select 1 row
Well, I think the error says it all. You have to limit the inner query somehow with WHERE condition, with TOP or with MAX(col3) for example. Depends WHICH col3 you want.
You need to join table_2 to table_3. Not sure what your database structure is, but it should be something like this:
INSERT INTO table_1(col_1,col_2,col_3)
SELECT t2.col_1, t2.col2, t3.col3
FROM table_2 t2
INNER JOIN table_3 t3 on t3.t2id = t2.id
The alternative is to use TOP 1, to just return 1 record in the sub-query - but I would not recommend this as it may not be the value you want:
INSERT INTO table_1(col_1,col_2,col_3)
SELECT col_1, col2, (SELECT top 1 col3 FROM table_3)
FROM table_2
You can use CTE to prepare your data :
;WITH MyData (col1, col2, col3)
AS
(
SELECT col_1, col2, CAST(CONVERT(varchar(10),(col3),112)AS int)
FROM table_2 JOIN table_3 ON <join condition>
)
INSERT INTO table_1(col_1,col_2,col_3)
SELECT col_1, col2, col3
FROM MyData
Pls try below query :
INSERT INTO table_1(col_1,col_2,col_3)
SELECT col_1, col2, isnull((SELECT TOP 1 cast(col3 as int) FROM table_3),0)
FROM table_2
What I mean is, say you have a table like:
Col1 Col2
---- ----
1 1
1 9
2 1
2 3
4 1
4 2
I want to get: Col1=4 and Col2=2, because Col1 has precendence. In other words, I want the largest value of Col1 and for that value the largest value of Col2 in a minimal T-SQL expression. It's almost like saying:
SELECT TOP 1 Col1, Col2
FROM MyTable
ORDER BY Col1, Col2 DESC
But doing this in such a way that the Col1, Col2 values are usable within another query.
Not really anything like MAX(Col1, Col2). If you wanted to simulate MAX ... GROUP BY X you could use
WITH T AS
(
SELECT Col1,
Col2,
ROW_NUMBER () OVER (PARTITION BY X ORDER BY Col1 DESC, Col2 DESC) AS RN
FROM MyTable
)
SELECT Col1,
Col2,
X
FROM T
WHERE RN= 1;
Like this? One row
SELECT ...
FROM
SOmeTable
JOIN
(
SELECT TOP 1 Col1, Col2
FROM MyTable
ORDER BY Col1, Col2 DESC
) foo ON S.Col1 = foo.Col1
Or per outer row?
SELECT ...
FROM
SOmeTable S
CROSS APPLY
(
SELECT TOP 1 Col2
FROM MyTable M
WHERE S.somecol = M.SomeCol
ORDER BY Col2 DESC
) foo
SELECT ...
FROM
SOmeTable S
CROSS APPLY
(
SELECT Col1, MAX(Col2) AS MaxCOl2
FROM MyTable M
GROUP BY Col1
) foo ON S.Col1 = foo.Col1
WITH t(Col1,maxCol1,maxCol2) AS (
SELECT
Col1,
MAX(Col1) OVER(),
MAX(Col2) OVER(PARTITION BY Col1)
)
SELECT TOP 1 maxCo11,maxCol2 FROM t WHERE Col1 = maxCol1
I need to get several columns form sql query. Then I have to filter this answer by the "distinct" values of one column, but in the output I need to have all columns, not only this which values has to be distinct. Can anybody help me? Order by clause is not an answer for me.
A,B,C,D
E,F,G,H
I,J,C,L
M,N,Z,H
Above is a simple rows output. Please have a look onto 3rd column. Let's assume that we don't know how many rows do we have. I need to select only rows which has distinct value in 3rd column. (C,G,Z) - We need to filter anyone from "C" rows.
I've arbitrarily chosen to use col1 to break ties on col3. You can adjust the order by portion of the partition to suit your needs.
/* Set up test data */
declare #test table (
col1 char(1),
col2 char(1),
col3 char(1),
col4 char(1)
)
insert into #test
(col1, col2, col3, col4)
select 'A','B','C','D' union all
select 'E','F','G','H' union all
select 'I','J','C','L' union all
select 'M','N','Z','H'
/* Here's the query */
;with cteRowNumber as (
select col1, col2, col3, col4,
row_number() over (partition by col3 order by col1) as RowNumber
from #test
)
select col1, col2, col3, col4
from cteRowNumber
where RowNumber = 1
Returns
col1 col2 col3 col4
----------------------------
A B C D
E F G H
M N Z H
ROLL UP or CUBE could be helpful for your problem, since they can aggregate (i.e. subtotal) data based on the GROUP BY and still return the individual rows.