Snowflake table replace nulls with multiple values - sql

I have database table at Snowflake, with NULL values.
id
month
a01
5
a02
6
b01
6
b04
NULL
I need transform it as this example:
id
month
a01
5
a02
6
b01
6
b04
7
b04
8
I must replace NULLs with multiple values (with 2 values: 7 and 8 - summer months). So from each NULL row I need to make two rows.

The simplest way to do this would be with two separate statements, one to insert an extra row and one to update the existing NULL value:
INSERT INTO tab (id, month)
SELECT id, 8 as month
FROM tab
WHERE month is NULL;
followed by
UPDATE tab
SET month = 7
WHERE month is NULL;
Result:
id
month
a01
5
a02
6
b01
6
b04
7
b04
8
See this db<>fiddle.

Related

Merge and copy columns into database view using sql

Simplified problem:
I have 3 tables with same structure: 2 columns, TIMESTAMP and VALUE.
Example
(I simplified timestamp and value for easier understanding):
Table A:
TIMESTAMP VALUE
1 a101
5 a105
9 a109
17 a117
Table B:
TIMESTAMP VALUE
3 b103
5 b105
8 b108
13 b113
Table C:
TIMESTAMP VALUE
9 c109
11 c111
13 c113
18 c118
View should contain TIMESTAMPs of all tables in one single column and one column for each VALUE column of each table:
View
TIMESTAMP A_VALUE B_VALUE C_VALUE
1 a101
3 b103
5 a105 b105
8 b108
9 a109 c109
11 c111
13 b113 c113
17 a117
18 c118
Is this possible using a view?
Many thanks for answers.

I am going bonkers with this one simple SQL question

Input table:
STAGE_NO
STAGE_ENTERED_DATE
0
2015-12-01 14:16:47
1
null
2
null
3
null
4
null
5
null
6
2017-02-12 0:00:00
7
2017-12-12 0:00:00
I want a new column that will give me the next stage_no where "stage_entered_date" is not-null.
This is the result that I am expecting:
STAGE_NO
STAGE_ENTERED_DATE
Next_Stage
0
2015-12-01 14:16:47
6
1
null
6
2
null
6
3
null
6
4
null
6
5
null
6
6
2017-02-12 0:00:00
7
7
2017-12-12 0:00:00
null
Disclaimer: Next_Stage column means next_stage where date is not null.
You can do this using the lead window function, ignoring nulls, and redefining nulls as the null in a different column using the IFF function:
with T1 as
(
select
COLUMN1::int as "STAGE_NO",
COLUMN2::timestamp as "STAGE_ENTERED_DATE"
from (values
('0','2015-12-01 14:16:47'),
('1',null),
('2',null),
('3',null),
('4',null),
('5',null),
('6','2017-02-12 0:00:00'),
('7','2017-12-12 0:00:00')
)
)
select STAGE_NO
,STAGE_ENTERED_DATE
,lead(iff(STAGE_ENTERED_DATE is not null, STAGE_NO, null))
ignore nulls over (partition by null order by STAGE_NO) as NEXT_STAGE
from T1
;
STAGE_NO
STAGE_ENTERED_DATE
NEXT_STAGE
0
2015-12-01 14:16:47.000000000
6
1
null
6
2
null
6
3
null
6
4
null
6
5
null
6
6
2017-02-12 00:00:00.000000000
7
7
2017-12-12 00:00:00.000000000
null
This will perform the stage calculation across the entire table. You probably have something like a customer, company, or some other "thing" that goes through these stages. You can specify what that is using a partition by clause in the window function. It's currently set to null, but you can simply change it to the column that defines the sets of rows for the phases.

SQL Aggregate Over Date Range

Whoever answers this thank you so, so much!
Here's a little snippet of my data:
DATE Score Multiplier Weighting
2022-01-05 3 4 7
2022-01-05 4 7 8
2022-01-06 5 2 4
2022-01-06 3 4 7
2022-01-06 4 7 8
2022-01-07 5 2 4
Each row of this data is when something "happened" and multiple events occur during the same day.
What I need to do is take the rolling average of this data over the past 3 months.
So for ONLY 2022-01-05, my weighted average (called ADJUSTED) would be:
DATE ADJUSTED
2022-01-05 [(3*4) + (4*7)]/(7+8)
Except I need to do this over the previous 3 months (so on Jan 5, 2022, I'd need the rolling weighted average -- using the "Weighting" column -- over the preceding 3 months; can also use previous 90 days if that makes it easier).
Not sure if this is a clear enough description, but would appreciate any help.
Thank you!
IF I have interpreted this correctly I believe a GROUP BY query will meet the need:
sample data
CREATE TABLE mytable(
DATE DATE NOT NULL
,Score INTEGER NOT NULL
,Multiplier INTEGER NOT NULL
,Weighting INTEGER NOT NULL
);
INSERT INTO mytable(DATE,Score,Multiplier,Weighting) VALUES ('2022-01-05',3,4,7);
INSERT INTO mytable(DATE,Score,Multiplier,Weighting) VALUES ('2022-01-05',4,7,8);
INSERT INTO mytable(DATE,Score,Multiplier,Weighting) VALUES ('2022-01-06',5,2,4);
INSERT INTO mytable(DATE,Score,Multiplier,Weighting) VALUES ('2022-01-06',3,4,7);
INSERT INTO mytable(DATE,Score,Multiplier,Weighting) VALUES ('2022-01-06',4,7,8);
INSERT INTO mytable(DATE,Score,Multiplier,Weighting) VALUES ('2022-01-07',5,2,4);
query
select
date
, sum(score) sum_score
, sum(multiplier) sum_multiplier
, sum(weighting) sum_weight
, (sum(score)*1.0 + sum(multiplier)*1.0) / (sum(weighting)*1.0) ADJUSTED
from mytable
group by date
result
+------------+-----------+----------------+------------+-------------------+
| date | sum_score | sum_multiplier | sum_weight | ADJUSTED |
+------------+-----------+----------------+------------+-------------------+
| 2022-01-05 | 7 | 11 | 15 | 1.200000000000000 |
| 2022-01-06 | 12 | 13 | 19 | 1.315789473684210 |
| 2022-01-07 | 5 | 2 | 4 | 1.750000000000000 |
+------------+-----------+----------------+------------+-------------------+
db<>fiddle here
Note: I have not attempted to avoid possible divide by 0 or any NULL value problems in the query ablove

Select column names based on max value by row

I need select column name based on max value by row. I have snowflake database table:
id cars_cat1 cars_cat2 cars_cat_3
a01 5 2 8
a02 6 1 5
a03 6 5 12
a04 3 9 1
Where is IDs and many categories with counts. I need new column, with category name, where count is max.
Output:
id max_category
a01 cars_cat_3
a02 cars_cat1
a03 cars_cat_3
a04 cars_cat2
I try window functions... without success.
You can use the function GREATEST() in a CASE expression:
SELECT id,
CASE GREATEST(cars_cat1, cars_cat2, cars_cat_3)
WHEN cars_cat1 THEN 'cars_cat1'
WHEN cars_cat2 THEN 'cars_cat2'
WHEN cars_cat3 THEN 'cars_cat3'
END max_category
FROM tablename

Max date among records and across tables - SQL Server

I tried max to provide in table format but it seem not good in StackOver, so attaching snapshot of the 2 tables. Apologize about the formatting.
SQL Server 2012
**MS Table**
**mId tdId name dueDate**
1 1 **forecastedDate** 1/1/2015
2 1 **hypercareDate** 11/30/2016
3 1 LOE 1 7/4/2016
4 1 LOE 2 7/4/2016
5 1 demo for yy test 10/15/2016
6 1 Implementation – testing 7/4/2016
7 1 Phased Rollout – final 7/4/2016
8 2 forecastedDate 1/7/2016
9 2 hypercareDate 11/12/2016
10 2 domain - Forte NULL
11 2 Fortis completion 1/1/2016
12 2 Certification NULL
13 2 Implementation 7/4/2016
-----------------------------------------------
**MSRevised**
**mId revisedDate**
1 1/5/2015
1 1/8/2015
3 3/25/2017
2 2/1/2016
2 12/30/2016
3 4/28/2016
4 4/28/2016
5 10/1/2016
6 7/28/2016
7 7/28/2016
8 4/28/2016
9 8/4/2016
9 5/28/2016
11 10/4/2016
11 10/5/2016
13 11/1/2016
----------------------------------------
The required output is
1. Will be passing the 'tId' number, for instance 1, lets call it tid (1)
2. Want to compare tId (1)'s all milestones (except hypercareDate) with tid(1)'s forecastedDate milestone
3. return if any of the milestone date (other than hypercareDate) is greater than the forecastedDate
The above 3 steps are simple, but I have to first compare the milestones date with its corresponding revised dates, if any, from the revised table, and pick the max date among all that needs to be compared with the forecastedDate
I managed to solve this. Posting the answer, hope it helps aomebody.
//Insert the result into temp table
INSERT INTO #mstab
SELECT [mId]
, [tId]
, [msDate]
FROM [dbo].[MS]
WHERE ([msName] NOT LIKE 'forecastedDate' AND [msName] NOT LIKE 'hypercareDate'))
// this scalar function will get max date between forecasted duedate and forecasted revised date
SELECT #maxForecastedDate = [dbo].[fnGetMaxDate] ( 'forecastedDate');
// this will get the max date from temp table and compare it with forecasatedDate/
SET #maxmilestoneDate = (SELECT MAX(maxDate)
FROM ( SELECT ms.msDueDate AS dueDate
, mr.msRevisedDate AS revDate
FROM #mstab as ms
LEFT JOIN [MSRev] as mr on ms.msId = mr.msId
) maxDate
UNPIVOT (maxDate FOR DateCols IN (dueDate, revDate))up );