SAS Sum daily date into weeks - sql-server

I am trying to take daily data (not every day has data) and sum it by weeks starting on monday. Below is a very small sample for the Data I have. the code is irrelvant for the summing purposes needed here.
Data have:
ID
PKG
Revdt
code
QTY
70
17AB
02AUG2021:00:00:00
01
7
70
17AB
04AUG2021:00:00:00
02
-10
70
17AB
05AUG2021:00:00:00
01
8
70
17AB
10AUG2021:00:00:00
01
7
70
17AB
1QAUG2021:00:00:00
01
7
73
12AC
02AUG2021:00:00:00
09
0
73
17AC
07AUG2021:00:00:00
01
7
Data want
ID
PKG
Revdt
code
QTY
70
17AB
02AUG2021:00:00:00
01
5
70
17AB
09AUG2021:00:00:00
01
14
73
12AC
02AUG2021:00:00:00
01
7
I have tried the below
Proc sql;
connect to odbc (dsn='' id='' p='');
create table work.WeeklySum as select distinct * from connection to odbc
(select ID, Pkg, datepart(week, revdt), code, sum(qty)
from datebase
group by datepart(week, revdt) );
disconnect from odbc;
quit;
However when i run it, it says "error:proc sql requires any created table to have atleast 1 column"

I would just pull the data with the daily rows first into SAS. If it is too big, write a macro to run it in loops with small chunks.
Once you get the daily dataset into SAS, create a separate table with weekly datetimes (here I am creating a table begins with Jan 1, 2021 and has a row for every week from there - change the inputs according to your need):
data weeks;
format week_date datetime19.;
do i = 0 to 52;
week_date = intnx('dtday', "01jan2021:00:00:00"dt, 7*i,'s');
output;
end;
drop i;
run;
Once you have this weeks dataset, left join your daily dataset to it using:
week_date <= revdt < intnx('dtday', week_date, 7, 's')
and then sum your variable by week_date.

select ID, Pkg, datepart(week, revdt), code, sum(qty)
from datebase
group by datepart(week, revdt)
This is not valid in SQL Server, so this will be your problem. SAS lets you do this, but when you do pass-through SQL, you have to follow their rules. In the case of SQL Server, every variable that is not part of a summary function (here, sum(qty) is the only summary function call) has to be part of the group by.
If you want to group by inside SQL Server, you'll have to modify your query to be a join from the (ID,Pkg) query to the (datepart,sum) query. SAS does this for you, but SQL Server won't.

Related

Split a record into multiple rows

I have two tables in SQL Server, Portfolio and Master. The portfolio holds inventory, while the master table defines the room types and number of bedrooms.
select
PropertyNumber,
Unit,
Rent,
Code
from Portfolio
The above query returns the following records:
01
111
500
2BD
01
112
200
1BD
While the below query returns the following:
select
Property,
Unit,
Duplex
from [Master]
01
1BD
1
01
2BD
2
01
3BD
3
I'm trying to split rows based on the Duplex column in my Master table. For example, in the initial output, I'd like to split that first record into two rows based on the 2BD data (and also divide the Rent column by that number). In other words, the final result would look like this:
01
111
250
2BD
01
111
250
2BD
01
112
200
1BD
I won't write your query for you, but I'll tell you how to do it, if I understand the question.
IIUC you want to produce N rows for master based on duplex.
To produce N rows, create a little table, perhaps like this:
select distinct duplex as n into #N
then
select m.* from master as m join #N
on duplex <= n
The rest is easy: extend the join to portfolio, and divide rent by duplex.

Get count of latest consecutive daily logins

I have a SQL table containing a list of the daily logins of the subscribers to my site. The rows contain the user id and the date and time of the first login of each day, which means there is a maximum of one record per day for each member.
Is there a way to use SQL to get a count of the number if consecutive daily logins for each member, that is the latest login streak?
I could do this programmatically (C#) by going through each record for a user in reverse order and stop counting when a day is missing, but I was looking for a more elegant way to do this through a SQL function. Is this at all possible?
Thanks!
Answer from comment
You can use Lag function https://msdn.microsoft.com/en-IN/library/hh231256.aspx
If your database compatibility level is lower than 110 you cant use Lag function
The following code must get the latest streak of logins for you (only when there is record for 1st login of the day)
suppose if your table of dates for a single user is
pk_id dates
----------- -----------
27 2017-04-02
28 2017-04-03
29 2017-04-04
30 2017-04-05
31 2017-04-06
44 2017-04-09
45 2017-04-10
46 2017-04-11
47 2017-04-12
48 2017-04-13
then
SELECT ROW_NUMBER() OVER(ORDER BY dates desc) AS Row#,dates into #temp1 FROM
yourTable where userid = #userid
select top 1 a.Row# As LatestStreak from #temp1 a inner join #temp1 b on a.Row# = b.Row#-1
where a.dates <> DATEADD(DAY,1,b.dates) order by a.Row# asc
this gives you 5, I have used Inner Join so that it wont have server compatibility issue
or you can use this, you can get the dates in the last streak too if you use c.dates instead of count(*)
SELECT COUNT(*)
FROM
(SELECT MAX (a.dates) AS Latest
FROM #yourtable a
WHERE DATEADD(DAY,-1,dates)
NOT IN (SELECT dates FROM #yourtable)) AS B
JOIN #yourtable c
ON c.dates >= b.Latest
This solution is probably similar to what you want:
How do I group on continuous ranges
It has a link to the motivating explanation here:
Things SQL needs: SERIES()
The main idea is that if after you have grouped by individual id's, and ordered by dates, the difference between date and current row is an invariant within each series of consecutive dates. So you group by user and this invariant (and min date within this group). And then you can group by user and pick the count of the 2nd column and only pick the max count.

SQL Query-Multiple date ranges

I want to fetch some data from DB by giving multiple date ranges. Example,in February I want to get weekly report from a table in this order Feb 01 to 07, Feb 07 to 14, Feb 14 to 21, Feb 21 to 28 and Feb 28 to Mar 01. In DB the records are stored in a daily wise not in weekly wise. I want to cluster it as weekly wise and calculate sum then show the result. Please help me if you know this case.
For clear cut view, consider 3 tables & its columns.
Table A:id,timestamp (comment-data is inserted daily)
Table B:id,fruits
Table C:id,fruits_type
Result:
fruits_type count(id) timestamp
apple 3 01-02-2016 to 07-02-2016
orange 5 01-02-2016 to 07-02-2016
pineapple 8 01-02-2016 to 07-02-2016
apple 4 07-02-2016 to 14-02-2016
orange 5 07-02-2016 to 14-02-2016
Conditions:id should match among 3 tables;fetch data by providing group by fruits_type and timestamp should be in weekly wise.
Please help if you know this
To get the sum of all values between two dates you would do it like this:
SELECT SUM(Column1)
FROM Table1
WHERE Date1 BETWEEN '2/1/2016' AND Date1 <'2/7/2016'
If you want to make it more flexible and have the query get the last week's sum you can use the DATEADD function to lag by one week:
SELECT SUM(Column1)
FROM Table1
WHERE Date1 BETWEEN DATEADD(week, -1, GETDATE()) AND Date1 < GETDATE()
If you want the result set to include a row for each week, you can use UNION to merge the queries.

T-SQL Pivoting approach

I have a View that has a structure similar to the following:
Id Name State ZipCode #Requests AmtReq Price Month Year
1 John IN 46202 203 33 $300 1 2015
1 Jane IN 46202 200 45 $100 2 2015
...
Queries require reports to be generated for given quarters (1st quarter will include the first three months ...) grouped by state
The result should look like this:
Ist Quarter ...
January February ...
State ZipCode #Requests AmtReq Price #Requests AmtReq Price ...
IN 46202 203 33 45 200 45 100
I feel that this can be done using pivoting but I do not have experience with it. I tried with single column pivoting and had some success, but not in this scale.
Another approach would be to create a stored procedure that will generate the data for me and then just fix some formating (e.g., the first two rows) in the client. Any suggestions on how to approach this problem?
I am using SQL Server as a DBMS.
If you have MS Excel on your machine then you can export the view to Excel and summarize it to a pivot table. From there you can create table and diagrams as you needed.

Comparing data in two tables,insert if data is not there,update if data is there

I have two tables
SELECT * FROM dbo.VMM_Table_20120210 table 1
and output of this table is
vehicle_Make vehicle_model
---------------------------
01 000
01 111
01 112
01 113
01 114
01 115
01 117
like this upto 993 records r there in the above table
and 2nd table is
SELECT * FROM dbo.TBL_VEHICLE_MODEL_NEW
and output of this table is
vmodel_id vmodel_vmake_code vmodel_type vmodel_code
---------------------------------------------------------------------------
1 01 t 7AV
2 01 c 7AE
UPTO 1107 records are there in this table
the requirement is I need to compare vehicle_make with vmodel_vmake_code and vehicle_model with vmodel_code and If data is not there in the 2nd table I need to insert it from the first table if data is there I need to update the data
I need it procedure with cursor in the procedure to loop the each row will u please help me in this situation
I am assuming that your tags are for SQL-Server, and not SQL and Server separately, so I am going to suggest the MERGE operation. There are some details that are pretty unclear from the question, such as what Update to perform when there is a match, and how to get values for vmodel_type and vmodel_Code, so I can't provide a perfect answer, but this should get you started:
MERGE INTO dbo.TBL_VEHICLE_MODEL_NEW t
USING dbo.VMM_Table_20120210 c
ON t.vmodel_vmake_code = c.vehicle_Make AND t.vmodel_code = c.vehicle_model
WHEN MATCHED THEN
UPDATE SET vmodel_type = 'A' -- CHANGE TO WHATEVER YOU WANT TO HAPPEN WHEN THE DATA EXISTS IN TABLE 2
WHEN NOT MATCHED THEN
INSERT VALUES (c.Vehicle_Make, c.Vehicle_Model, 't', '7AV');
-- WHATEVER YOU WANT TO HAPPEN WHEN THE RECORD IN TABLE 1 DOES NOT EXIST IN TABLE 2
See MSDN for more on MERGE.

Resources