Partition by with conditions - sql-server

I have a table which contains info on customer purchases per year and month respectively. Here is a simplified version.
id
year
month
nb_purch
1
2001
1
1
1
2001
2
4
1
2001
3
7
...
...
...
...
1
2001
12
3
1
2003
1
3
1
2003
2
2
1
2003
3
5
1
2003
4
7
...
...
...
...
1
2003
12
3
2
2001
1
3
2
2001
2
2
2
2001
3
5
2
2001
4
7
Basically there are several constraints. The database contains only the years when the client has made a purchase. If the client has made a purchase within the year X then X will be divided into 12 rows according to months. The months with no purchases have the value 0.
What I am trying to do is to retrieve the number of purchases per certain "windows". Currently its value sits at 3 years. For example i want to retrieve the sum of nb_purch within the last 3 years starting from 2003 march. This means i need to add all values from
march 2001 to march 2003.
SELECT SUM(nb_purch) OVER (PARTITION BY id ORDER BY year, month ASC ROWS BETWEEN 36 PRECEDING AND CURRENT ROW) AS LAST_3_YEARS FROM T
The issue i am facing here is that the table does not contain all years and therefore in my example of purchases between (2001 and 2003) if the year 2002 is missing then i am getting false results. I would like to avoid having to add all missing years and fill them with NULL values for each customer.

Related

How to track changes in the board of directors within the same firm

In Stata I need to create a new variable "changes in the board of directors" which indicates whether the same directors are observed in the same firm over time. Consider an example below:
clear
input dirid firmid year
1 10 2006
2 10 2006
3 10 2006
1 10 2007
2 10 2007
3 10 2007
1 10 2008
2 10 2008
3 10 2008
4 10 2008
3 10 2009
4 10 2009
end
Directors ID 1, 2, and 3 are in firm 10 in 2006 and in 2007. So there was no change in the board of directors from t-1 to t. The variable "changes in the board of directors" should be 0. However, in 2008 a new director came to the board dirid = 4, so there was a change in the board and the variable should be 1. The same in 2009 because dirid 1 and 2 left the company. So any change, whether the entrance or exit of directors, should be reported with 1 in the new binary variable.
Here's another way to do it. I think it should cope with directors leaving and later coming back.
clear
input dirid firmid year
1 10 2006
2 10 2006
3 10 2006
1 10 2007
2 10 2007
3 10 2007
1 10 2008
2 10 2008
3 10 2008
4 10 2008
3 10 2009
4 10 2009
end
bysort firmid year (dirid) : gen board = strofreal(dirid) if _n == 1
by firmid year : replace board = board[_n-1] + " " + strofreal(dirid) if _n > 1
by firmid year : replace board = board[_N]
by firmid : gen anychange = year != year[_n-1] & board != board[_n-1]
bysort firmid year (anychange) : replace anychange = anychange[_N]
sort firmid year dirid
list, sepby(firmid year)
+--------------------------------------------+
| dirid firmid year board anycha~e |
|--------------------------------------------|
1. | 1 10 2006 1 2 3 1 |
2. | 2 10 2006 1 2 3 1 |
3. | 3 10 2006 1 2 3 1 |
|--------------------------------------------|
4. | 1 10 2007 1 2 3 0 |
5. | 2 10 2007 1 2 3 0 |
6. | 3 10 2007 1 2 3 0 |
|--------------------------------------------|
7. | 1 10 2008 1 2 3 4 1 |
8. | 2 10 2008 1 2 3 4 1 |
9. | 3 10 2008 1 2 3 4 1 |
10. | 4 10 2008 1 2 3 4 1 |
|--------------------------------------------|
11. | 3 10 2009 3 4 1 |
12. | 4 10 2009 3 4 1 |
+--------------------------------------------+
See also [this paper][1] on concatenating rowwise.
[1]: https://journals.sagepub.com/doi/full/10.1177/1536867X20909698
clear
input dirid firmid year
1 10 2006
2 10 2006
3 10 2006
1 10 2007
2 10 2007
3 10 2007
1 10 2008
2 10 2008
3 10 2008
4 10 2008
3 10 2009
4 10 2009
end
bysort firmid year (dirid): gen n = _n
reshape wide n, i(firmid year) j(dirid)
egen all_directors = concat(n*)
bysort firmid (year): gen change = all_directors != all_directors[_n-1] & _n > 1
reshape long
drop if missing(n)
drop all_directors n

SQL Server 2016 - Transpose row to columns

I'm trying to figure out if it's possible to transform table rows to columns where the number of rows included changes at the time of the query. Here's a sample of what I'm trying to do:
Characteristics Table
strategy
year
month
aaa
aa
a
InvestmentA
2020
12
5
4
10
InvestmentB
2020
12
8
15
25
Investment(n)
2020
12
x
x
x
Output
year
month
Credit Type
InvestmentA
InvestmentA
Investment(n)
2020
12
aaa
5
8
x
2020
12
aa
4
15
x
2020
12
a
10
25
x

Return the first non-zero in a column/row in tableau

I am trying to return the appearance of first non-zeros in a row. The variable I want to return is Fiscal Year that when each customer first started to buy the product.
In my case, I would like to return the Year they first started. The first appearance of "1" in each row represents when they started for the first time, so I want to return the Year for that customer when that first number appears.
ID 1950 1951 1953 1955 1959 1965 1968 1972 1974 1975 1976
1 1 1 1 1 1 1
2 1
3 1 1 1
4 1 1 1 1
5 1 1
6 1
7 1
8 1 1
9
10 1 1 1 1 1
11 1 1 1 1
12 1
Use a level-of-detail (LOD) calculation. An LOD allows you to apply a calculation, in this case min() to a dataset for a given set of dimensions. You will need to decide whether to used FIXED or INCLUDE for your particular situation (they behave differently in the presence of filters). I'm making an assumption that your ID column is a customer Id.
{ INCLUDE [ID] : Min([Fiscal Year])}
Much more info available in the online help documents at https://onlinehelp.tableau.com/current/pro/desktop/en-us/calculations_calculatedfields_lod_overview.html.

Difference between weeks in MDX

How I can calculate difference between each week and 2 weeks ago, for a given measure in MDX?
WEEK MEASURE NEW_MEASURE
---- ------- -----------
1 10 NULL
2 5 NULL
3 20 10
4 10 5
5 40 20
Below Members work, but only without CASE statement so I have to calculate it separately:
MEMBER [Measures].[12 Week temp]
AS
([Date].[Week Year].CurrentMember, [Measures].[Total Orders]) -
([Date].[Week Year].lag(13), [Measures].[Total Orders])
MEMBER [Measures].[12 Week]
AS
CASE WHEN [Measures].[12 Week temp] = [Measures].[Total Orders] THEN 0 ELSE [Measures].[12 Week temp] END

SAS Creating entries by group

I have an array that I want to add years and months sequentially to using a SAS program:
Original:
ID
1
2
3
End result:
ID YEAR; MONTH
1 2014 11
1 2014 12
1 2015 1
1 2015 2
1 2015 3
2 2014 11
2 2014 12
2 2015 1
2 2015 2
2 2015 3
3 2014 11
3 2014 12
3 2015 1
3 2015 2
3 2015 3
I also need to set the upper lower limits for the years and months I want to add to the table.
Any help is appreciated. Thanks!
As the comments suggest, I'm taking a bit of a guess on what you're looking for. From what you're asking, I'd recommned using a data step to loop through your original data, outputing multiple rows for each line in the original data.
This uses intnx to advance to the next month (intnx documentation)
*Enter start and end date here;
%Let startdt = '01NOV2014'd;
%Let enddt = '01MAR2015'd;
data want (drop=_date);
set original;
*Create multiple records for each observation in 'original'- one for each month;
_date = &startdt;
DO UNTIL (_date > &enddt);
year = year(_date);
month = month(_date);
output;
*Advance to next month;
_date = intnx('month', _date, 1, 'beginning');
END;
run;

Resources