How to use UNPIVOT in SQL Server - sql

I have a table StoreDetails with the following data.
Store 1 2 3
-------------------------------
101 138 282 220
102 96 212 123
105 37 78 60
109 59 97 87
My required output is:
Store Week xCount
---------------------------------
101 1 138
102 1 96
105 1 37
109 1 59
101 2 282
102 2 212
105 2 78
109 2 97
101 3 220
102 3 123
105 3 60
109 3 87
How can I get this result set using UNPIVOT?

I prefer using cross apply:
select sd.store, v.week, v.xcount
from storedetails sd cross apply
(values (1, sd.[1]), (2, sd.[2]), (3, sd.[3]), (4, sd.[4])
) v(week, xcount);
Why do I prefer apply over unpivot? unpivot is very specific syntax that does only one thing (and is specific to SQL Server and Oracle).
On the other hand, apply is an introduction to lateral joins. These are very powerful and unpivoting is just one thing that they can do.

you can try below-
select store,week, xcount
from StoreDetails
unpivot
(
xcount for week in (1,2,3)
)up

Related

What is the best why to aggregate data for last 7,30,60.. days in SQL

Hi I have a table with date and the number of views that we had in our channel at the same day
date views
03/06/2020 5
08/06/2020 49
09/06/2020 50
10/06/2020 1
13/06/2020 1
16/06/2020 1
17/06/2020 102
23/06/2020 97
29/06/2020 98
07/07/2020 2
08/07/2020 198
12/07/2020 1
14/07/2020 168
23/07/2020 292
No we want to see in each calendar date the sum of the past 7 and 30 days
so the result will be
date sum_of_7d sum_of_30d
01/06/2020 0 0
02/06/2020 0 0
03/06/2020 5 5
04/06/2020 5 5
05/06/2020 5 5
06/06/2020 5 5
07/06/2020 5 5
08/06/2020 54 54
09/06/2020 104 104
10/06/2020 100 105
11/06/2020 100 105
12/06/2020 100 105
13/06/2020 101 106
14/06/2020 101 106
15/06/2020 52 106
16/06/2020 53 107
17/06/2020 105 209
18/06/2020 105 209
so I was wondering what is the best SQL that I can write in order to get it
I'm working on redshift and the actual table (not this example) include over 40B rows
I used to do something like this:
select dates_helper.date
, tbl1.cnt
, sum(tbl1.cnt) over (order by date rows between 7 preceding and current row ) as sum_7d
, sum(tbl1.cnt) over (order by date rows between 30 preceding and current row ) as sum_7d
from bi_db.dates_helper
left join tbl1
on tbl1.invite_date = dates_helper.date

how to add a constant value (1) in an empty column in snowflake-matillion

my table looks like
id total avg test_no
1 445 89
2 434 85
3 378 75
4 421 84
I'm working on matillion-snowflake
I need my result to look like
id total avg test_no
1 445 89 1
2 434 85 1
3 378 75 1
4 421 84 1
Just use a Calculator component and set the value of the calculated column to 1
In Snowflake, you would modify the table using:
update t
set test_no = 1;
I assume that Matillion supports this as well.

SQL Query to order data based on other column value

I have the below set of data(current data), where system_id is the ID of the particular system. And pre_system_id's are ID of system where it is dependent. Now I need the order in such a way that rows with no dependent system should come first , then rows with one dependent system come second and so on.
The current result:
System_ID PRE_SYSTEM_ID1 PRE_SYSTEM_ID2 PRE_SYSTEM_ID3 PRE_SYSTEM_ID4
106 100
105
112 105 100 109
100
109 100 105
119 100 109 105 112
102 112 109
104 109 106
The actual result should be like below:
Order System_ID PRE_SYSTEM_ID1 PRE_SYSTEM_ID2 PRE_SYSTEM_ID3 PRE_SYSTEM_ID4
1 100
2 105
3 106 100
4 109 100 105
5 112 105 100 109
6 119 100 109 105 112
7 104 109 106
8 102 112 109 104
The query for the current result is simply
Select * from ImpactedSystem;
Sorting by the various PRE_SYSTEM_IDn columns using the nulls first clause should produce the order you want:
select *
from ImpactedSystem
order by PRE_SYSTEM_ID1 nulls first,
PRE_SYSTEM_ID2 nulls first,
PRE_SYSTEM_ID3 nulls first,
PRE_SYSTEM_ID4 nulls first,
SYSTEM_ID
Finally sort by SYSTEM_ID, to order the values with no dependent IDs.
you can use the below query to obtain the result as well.
select *
from Current_data
order by DECODE(pre_system_td1,null,1),
DECODE(pre_system_td2,null,1),
DECODE(pre_system_td3,null,1),
DECODE(pre_system_td4,null,1);

group by column not having specific value

I am trying to obtain a list of Case_Id's where the case does not contain a specific RoleId using Microsoft Sql Server 2012.
For example, I would like to obtain a collection of Case_Id's that do not contain a RoleId of 4.
So from the data set below the query would exclude Case_Id's 49, 50, and 53.
Id RoleId Person_Id Case_Id
--------------------------------------
108 4 108 49
109 1 109 49
110 4 110 50
111 1 111 50
112 1 112 51
113 2 113 52
114 1 114 52
115 7 115 53
116 4 116 53
117 3 117 53
So far I have tried the following
SELECT Case_Id
FROM [dbo].[caseRole] cr
WHERE cr.RoleId!=4
GROUP BY Case_Id ORDER BY Case_Id
The not exists operator seems to fit your need exactly:
SELECT DISTINCT Case_Id
FROM [dbo].[caseRole] cr
WHERE NOT EXISTS (SELECT *
FROM [dbo].[caseRole] cr_inner
WHERE cr_inner.Case_Id = cr.case_id
AND cr_inner.RoleId = 4);
Just add a having clause instead of where:
SELECT Case_Id
FROM [dbo].[caseRole] cr
GROUP BY Case_Id
HAVING SUM(case when cr.RoleId = 4 then 1 else 0 end) = 0
ORDER BY Case_Id;

oracle query - something similar to pivot, but

I have a table like this:
ID_ORIG ID_DEST DISTANCE
------- ------- --------
1 101 10
1 102 15
1 103 20
2 101 25
2 102 30
2 103 35
3 101 40
3 102 45
3 103 50
And I want the following result:
ID_ORIG 101 102 103
------- --- --- ---
1 10 15 20
2 25 30 35
3 40 45 50
I tried to use 'pivot', but obiously didn't achive this result. Database is Oracle 11g.
Any help would be appreciated.
Please try:
select * From(
select * from YourTable
) PIVOT (sum(DISTANCE) for (ID_DEST) IN (101, 102, 103));
SQL Fiddle Demo