Select rows where count of grouped data =2 - sql

I have to get the users, which appear at least two weeks before and after the given date. So lets say I have data:
userName date week
user1 27 10 2011 44
user1 27 10 2011 44
user1 27 10 2011 44
user2 21 04 2011 17
user2 29 04 2011 17
user2 02 05 2011 19
user2 03 05 2011 19
user2 16 05 2011 21
user2 23 05 2011 22
user3 06 01 2011 24
user3 14 05 2011 25
user3 20 05 2011 26
user3 27 05 2011 27
and I need to get the results first grouped by user and week, then I need to count how many weeks the user appears before (lets say week 20) and after, and then select only ones who appears at least 2 weeks before and after, so in my case I would get the result
user2
Unfortunately I cannot create viewTable because of the database restrictions. this query is giving me only the first part of the results, data grouped by user and week, but I have no idea how to count grouped data:
SELECT username,
min(a.actionDate) as date,
datepart(wk,a.actionDate) as week
FROM Table1 a
GROUP BY username ,
datepart(wk,amd.actionDate)
thanks for any help.

To return users which have date records at least two weeks before and two weeks after a specified date, try:
select username
from Table1
group by username
having datediff(wk, min(actiondate), #date) >= 2 and
datediff(wk, #date, max(actiondate)) >= 2

Related

Identify if date is the last date for any given group?

I have a table that is structured like the below - this contains details about all customer subscriptions and when they start/end.
SubKey
CustomerID
Status
StartDate
EndDate
29333
102
7
01 jan 2013
1 Jan 2014
29334
102
6
7 Jun 2013
15 Jun 2022
29335
144
6
10 jun 2021
17 jun 2022
29336
144
2
8 oct 2023
10 oct 2025
I am trying to add an indicator flag to this table (either "yes" or "no") which shows me by each row, if when the [EndDate] of the SubKey is the last one for that CustomerID. So for the above example..
SubKey
CustomerID
Status
StartDate
EndDate
IsLast
29333
102
7
01 jan 2013
1 Jan 2014
No
29334
102
6
7 Jun 2013
15 Jun 2022
Yes
29335
144
6
10 jun 2021
17 jun 2022
Yes
29336
144
2
8 oct 2023
10 oct 2025
Yes
The flag is set to No for the first row, because on 1 Jan 2014, customerID 102 had another SubKey (29334) still active at the time (which didn't end until 15 jun 2022)
The rest of the rows are set to "Yes" because these were the last active subscriptions per CustomerID.
I have been reading about the LAG function which may be able to help. I am just not sure how to make it fit in this scenario.
Probably the easiest method would to use exists with a correlation. Can you try the following for your desired results for excluding rows without an overlap:
select *,
case when exists (
select * from t t2
where t2.customerId = t.customerId
and t2.enddate > t.enddate
and t2.startDate < t.Enddate
) then 'No' else 'Yes' end as IsLast
from t;

How to display the oldest date for a unique user who has multiple dates in a database?

Let's say that my output looks like this (simplified example):
UserName
ProfileCreation
PurchasePrice
PurchaseDate
Alice
Dec 21 2019 6:00AM
120.00
Dec 21 2019 8:00AM
Alice
Dec 21 2019 6:00AM
90.00
Dec 25 2019 9:00AM
Alice
Dec 21 2019 6:00AM
150.00
Jan 02 2020 10:00AM
Bob
Jan 01 2020 9:00PM
50.00
Jan 03 2020 11:00PM
Bob
Jan 01 2020 9:00PM
70.00
Jan 07 2020 11:00PM
The code for this output would look like this, I guess (not that important):
SELECT
UserName, ProfileCreation, PurchasePrice, PurchaseDate
FROM Some_Random_Database
But my desired output should look like this:
UserName
ProfileCreation
PurchasePrice
FirstPurchaseDate
NumberOfPurchases
AvgOfPurchasePrice
Alice
Dec 21 2019
120.00
Dec 21 2019
3
120.00
Bob
Jan 01 2020
50.00
Jan 03 2020
2
60.00
Hopefully, it's understandable what my goal is - to have unique user with date of his/her oldest purchase and with some calculated metrics for all purchases. Price of the first purchase can stay, but it is not necessary.
I'm writing in SOQL dialect - Salesforce Marketing Cloud.
Obviously, I've got some ideas how to do some of the intended tweaks in my code, but I'd like to see a solution from any expert who is willing to show me the best way possible. I'm really just a noob :-)
I appreciate any help, guys!
Note: i know nothing about Salesforce Marketing Cloud, but...
There's few ways to achieve that:
#1 - standard sql
SELECT UserName, ProfileCreation
, MIN(PurchaseDate) FirstPurchaseDate
, COUNT(PurchasePrice) NoOfPurchases
, AVG(PurchasePrice) AvgPurchasePrice
FROM Foo
GROUP BY UserName, ProfileCreation;
#2 - window functions
SELECT DISTINCT UserName, ProfileCreation
, MIN(PurchaseDate) OVER(PARTITION BY UserName ORDER BY UserName) FirstPurchaseDate
, COUNT(PurchasePrice) OVER(PARTITION BY UserName ORDER BY UserName) NoOfPurchases
, AVG(PurchasePrice) OVER(PARTITION BY UserName ORDER BY UserName) AvgPurchasePrice
FROM Foo;
SELECT
UserName, ProfileCreation, PurchasePrice, PurchaseDate
FROM
Some_Random_Database
WHERE
(UserName, PurchaseDate) IN
(SELECT UserName, max(PurchaseDate) FROM Some_Random_Database GROUP BY UserName);

How to join two columns from one table to a different table based matching criteria in SAS

I am trying to join the columns "Type2" and "Measurement2" from table "Update" to the table "Have". I want the columns to align where column "Subject1" in table "Have" matches column "Subject2" in table "update", and column "Procedure1" in table "Have" matches column "Procedure2" in table "Update".Thank you in advance.
data Have;
input Subject1 Type1 :$12. Date1 &:anydtdte. Procedure1 :$12. Measurement1;
format date yymmdd10.;
datalines;
500 Initial 15 AUG 2017 Invasive 20
500 Initial 15 AUG 2017 Surface 35
428 Initial 3 JUL 2017 Outer 10
765 Initial 20 JUL 2019 Other 19
610 Initial 17 Mar 2018 Invasive 17
;
data Update;
input Subject2 Type2 :$12. Date2 &:anydtdte. Procedure2 :$12. Measurement2;
format date yymmdd10.;
datalines;
500 Followup 15 AUG 2018 Invasive 54
428 Followup 15 AUG 2018 Outer 29
765 Seventh 3 AUG 2018 Other 13
500 Followup 3 JUL 2018 Surface 98
610 Third 20 AUG 2019 Invasive 66
;
Are you just looking for a join between two tables ??
Select distinct have.*, update.type2, update.measurement2
from have
left join update
on
have.subject1 = update.subject2
and have.procedure1 = update.procedure2
Combining two data sets based on a key (your subject and procedure) is performed using a MERGE according to the group variables named in a BY statement. Both data sets need the same BY variables.
Example code:
MERGE requires sorted data, so that will have to occur first.
Data set option rename= is used to create common names for the BY statement.
proc sort data=Have; by Subject1 Procedure1;
proc sort data=Updates; by Subject2 Procedure2;
data combined;
* trick: force these variables to be first two columns in output data set;
retain subject procedure;
merge
have (rename=(subject1=subject procedure1=procedure))
updates (rename=(subject2=subject procedure2=procedure))
;
by subject procedure;
run;
Example data:
data Have;
attrib
Subject1 length=8
Type1 length=$12
Date1 informat=anydtdte. format=yymmdd10.
Procedure1 length=$12
Measurement1 length=8
;
input
Subject1& Type1& Date1& Procedure1& Measurement1&; datalines;
500 Initial 15 AUG 2017 Invasive 20
500 Initial 15 AUG 2017 Surface 35
428 Initial 3 JUL 2017 Outer 10
765 Initial 20 JUL 2019 Other 19
610 Initial 17 Mar 2018 Invasive 17
;
data Updates;
attrib
Subject2 length=8
Type2 length=$12
Date2 informat=anydtdte. format=yymmdd10.
Procedure2 length=$12
Measurement2 length=8
;
input
Subject2& Type2& Date2& Procedure2& Measurement2&; datalines;
500 Followup 15 AUG 2018 Invasive 54
428 Followup 15 AUG 2018 Outer 29
765 Seventh 3 AUG 2018 Other 13
500 Followup 3 JUL 2018 Surface 98
610 Third 20 AUG 2019 Invasive 66
;

I have set of jobs record for whole month and want to display qty of jobs date wise in SQL

We have thousands of record in our data and want to count date wise jobs with category through single query. It is Possible?
Display required as under
TypesJobs 01 02 03 04 05 06 07
A 2 1 6 4 1 3 4
B 10 12 8 10 12 9 13
C 3 5 4 3 2 5 4
Here Types of jobs count for a day in date column 01, 02, 03 are date range of the month
You can use conditional aggregation, something like this:
select typesjobs,
sum(case when month(datecol) = 1 then 1 els e0 end) as month_01,
sum(case when month(datecol) = 2 then 1 els e0 end) as month_02,
. . .
from t
where <date condition here>
group by typesjobs;

How to calculate Rank SQL query

HI, I have the following table which save agent ranking on daily basis on basis of tickets status.
No. **Agent Name** **Incidents** **workorder** **Rank** **TimeStamp**
1 cedric 200 29 1 21 Jan 2011
2 poul 100 10 2 21 Jan 2011
3 dan 200 20 1 21 Jan 2011
4 cedric 100 19 2 22 Jan 2011
5 poul 200 26 1 22 Jan 2011
6 dan 150 20 2 22 Jan 2011
Now i need query which fetch ranking between two dates means if i select date between 21 jan 2011 to 22 jan 2011 then query return me agents average ranking between these two dates of agent not return the agent ranking details on date wise. I need single name of agent with his ranking.
Regards,
Iftikhar hashmi
Try
SELECT [Agent Name], AVG(RANK) FROM MY_TABLE WHERE [TimeStamp] BETWEEN DATE1 AND DATE2
GROUP BY [Agent Name]
(Update)
Thanks to Martin which reminded me I need to cast RANK.
SELECT [Agent Name], AVG(CAST(RANK AS FLOAT)) FROM MY_TABLE WHERE [TimeStamp] BETWEEN DATE1 AND DATE2
GROUP BY [Agent Name]