How do I calculate how many times something occurs in a 7 day period? - sql

I have an Excel sheet of 1 million rows that span 12 months from January 2020-January 2021. I have to display all of the attributes for the output.
This is an example of the 2 attributes I'm looking at for the code, but there are 15 attributes in total:
Attribute: Subscriber_Number |   Date_Email_Sent 
19202                     03Dec2020
12829                     03Dec2020 
13455                    05Dec2020
13455                    05Dec2020
13455                   02 Dec2020
13455                   04 Dec2020
An email cannot be sent to a subscriber more than 3 times a week. If that happens, that would become an issue. My goal is to find subscribers who have been called more than 3 times a week. In the example data I gave, the code output should show that Subscriber 13455 was called 4 times in a week. The code output should NOT include 12829 because it just occurs one time. 
This is a code that I tried:  
PROC SQL;
Select week (Date_Email_Sent, 'u') as weeknum, COUNT(Subscriber_Number) as per_week FROM Data;
Where SubscriberNumber >2
Group By week(Date_Email_Sent, 'U')
quit;
I got a large results were detected line, so I discarded results. There shouldn't be that many times that an email was sent to a subscriber (<10,000 instances), so I'm sure that I wrote the code incorrectly.

With standard sql, you can find those records using:
select Subscriber_Number, Date_Email_Sent
from Data
group by Subscriber_Number, Date_Email_Sent
having count(*) > 3

If you want subscribers who received more than 3 emails in a calendar week, then the logic should look like this:
PROC SQL;
Select week(Date_Email_Sent, 'u') as weeknum, Subscriber_Number,
count(*) as per_week
from Data;
Where SubscriberNumber >2
Group By week(Date_Email_Sent, 'U'), Subscriber_Number
having count(*) > 3;
quit;

Related

Structuring looker Explore Results

I’m having trouble figuring out how to count publications in my Looker data set by year and author. In my Looker explore the data Looker table results look like this:
Pub_id
year
author
author_id
1_1
2021
john
5.5
1_2
2020
john
5.5
  1_3 
2021
jane
2.0     
  1_4 
2021
jane
2.0     
  1_5 
2019
garth
3.6     
  1_6 
2013
wayne
1.7     
I want to create a bar chart that gives me the total number of publications per year, so:
                                           x
                                           x
  x             x          x            x
2013    2019    2020     2021
My struggle is getting the count or aggregate of the count correct.
I’m also trying to crate an aggregate count by authors, so output would look like:
Author
Number of publications
John  
         2           
Jane 
         2           
Wayne 
         1           
Garth 
         1           
Thanks for help or advice!
Both of these aggregations should use a single dimension and a single measure. For both, the measure should be a simple count:
view: my_view {
measure: number_of_publications {
type: count
}
}
Then in the explore, you should only select this measure and a single dimension (year for the first one and Author for the second), and you'll end up with a table like the one you posted above for Author.
Once you have the table, just select the bar chart type and you should be good to go.

How to join SQL query in sqlite?

How can I write second query instead of 'users_statistic' in first query?
SELECT *
from 'users' LEFT JOIN 'users_statistic'
ON users.id=users_statistic.user_id
SELECT *, SUM(clicks) as sum_clicks, SUM(page_views) as sum_page_views
FROM 'users_statistic'
GROUP BY user_id
Second query return table
user_id    sum_clicks       sum_page_clicks
1                 754                         543
2                 234                          987
In table 'users' is field id, which equivalent user_id in table 'users_statistic'. Also there are no fields sum_clicks and sum_page_clicks in table 'users'. I want to add fields sum_clicks and sum_page_clicks from second query to table 'users'
You can do the aggregation directly in the 1st query:
SELECT u.id, u.name,
COALESCE(SUM(s.clicks), 0) sum_clicks,
COALESCE(SUM(s.page_views), 0) sum_page_views
FROM users u LEFT JOIN users_statistic s
ON u.id = s.user_id
GROUP BY u.id
I use COALESCE() so that you get 0 instead of null if for a user there are no clicks or page views.

How to format SQL subquery to produce new and old data

I have a database where I am trying to figure out this problem. I want to write a SQL query to list all patients whose information has changed during their future visits. A future visit is defined as dbo.patientvisit.encounter_id < dbo.visitvitalstat.encounter_id The outputs I want in the table are the columns patient number, old and new race values, old and new gender values, and both encounter ids from the both tables. The new race and gender values are from future visits.
This is the code I have so far but I can't figure out how to get the new gender and new race values.
SELECT pv.patient_nbr,pv.encounter_id, vvs.race, vvs.gender, vvs.encounter_id
FROM PatientVisit pv
LEFT JOIN VisitVitalStat vvs
ON pv.encounter_id = vvs.encounter_id
WHERE pv.encounter_id < vvs.encounter_id;
This is the result I should get back:
SELECT  fpv.patient_nbr(??)
                vvs.race as "Old race",
                fv.newrace as "New Race",
                vvs.gender as "Old Gender",
                fv.newgender as " New Gender",
                vvs.encounter_id as "Old Encounter ID" ,
                fv.newencounter as "New Encounter ID"
FROM  VisitVitalStat vvs
INNER JOIN
                    ( SELECT fpv.patient_nbr as newnbr,
                                      fvvs.race as newrace,
                                      fvvs.gender as newgender,
                                      fvvs.encounter_id as newencounter
FROM PatientVisit fpv, VisitVitalStat fvvs
                      WHERE  fpv.encounter_id = fvvs.encounter_id
                              AND
                                      fpv.encounter_id < fvvs.encounter_id) fv
ON   fv.newencounter = vvs.encounter_id;
So I was able to write a query but I feel like it is still off, I'm not sure how to get patient number into all of this.
One method uses lag():
select pv.*
from (select pv.*,
lag(gender) over (partition by patient_nbr order by encounter) as prev_gender,
lag(race) over (partition by patient_nbr order by encounter) as prev_race,
lag(encounter) over (partition by patient_nbr order by encounter) as prev_encounter
from patientvisit pv
) pv
where prev_gender <> gender or prev_race <> race;
You can adapt this solution. Where b1 will be the old data and b2 the new data.
with base as (
select
patient_nbr
,encounter_id
,row_number() over (partition by patient_nbr order by encounter_id asc) as row
from patientvisit
LEFT JOIN VisitVitalStat vvs
ON pv.encounter_id = vvs.encounter_id
)
select b1.patient_nbr
,b1.encounter_id as old
,b2.encounter_id as new
,b1.gender as old
,b2.gender as new
,b1.race as old
,b2.race as new
from base b1
join base b2 on
b1.patient_nbr=b2.patient_nbr
and b1.row+1=b2.row

Consulting if a record exist before inserting in Oracle

I'm developing a query in oracle which consults if certain record doesn't exist (SELECT) for making the INSERT step, this is my code
IF
   (SELECT COUNT(*) FROM (SELECT * FROM HEX_KE_LOC WHERE CLVE_LOC = '20000')) = 0
THEN
   {INSERT INTO
           HEX_KE_LOC (CLVE_LOC,CLVE_STDO,MUN,CLVE_PAIS,UID_BUS_UNI,CLVE_ALTR,DSC,CIT,ZIPCODE)
   VALUES  
           ('20000','AGS','001','MX','0014','1','Zona Centro','01','20000');
     }
END IF;
but I can't make it work, any help I'll appreciate
My preferred way to do this is with a MERGE statement with no update clause:
MERGE INTO HEX_KE_LOC USING dual
ON ( CLVE_LOC = '20000' )
WHEN NOT MATCHED THEN INSERT (CLVE_LOC,CLVE_STDO,MUN,CLVE_PAIS,UID_BUS_UNI,CLVE_ALTR,DSC,CIT,ZIPCODE)
VALUES ('20000','AGS','001','MX','0014','1','Zona Centro','01','20000');

Repeating rows based on column value in each row

I've this table with the following data
Job  Quantity Status Repeat 
1    100      OK     2 
2    400      HOLD   0 
3    200      HOLD   1 
4    450      OK     3 
Based on the value in the Repeat column for each row, the row should be repeated again. For example for the Job 1, Repeat value is 2 so the Job 1 should repeat two more times.
The resultant table should be as below
Job    Quantity Status Repeat 
1      100       OK     2 
1      100       OK     2 
1      100       OK     2 
2      400       HOLD   0 
3      200       HOLD   1 
3      200       HOLD   1 
4      450       OK     3 
4      450       OK     3 
4      450       OK     3 
4      450       OK     3 
Can someone please help me out with this query?
am using oracle 10g
You could use a recursive CTE:
with cte(Job, Repeat, i) as
(
select Job
, Repeat
, 0
from YourTable
union all
select Job
, Repeat
, i + 1
from cte
where cte.i < cte.Repeat
)
select *
from cte
order by
Job
, i
Live example at SQL Fiddle.
Supposing you won't generate more than 1000 rows per row:
with num as (select level as rnk from dual connect by level<=1000)
select Job, Quantity, Status, Repeat, rnk
from t join num on ( num.rnk <= repeat )
order by job, rnk;
Here is a test:
http://sqlfiddle.com/#!4/4519f/12
UPDATE: As Jeffrey Kemp said, you can "detect" the maximum with a subquery:
with num as (select level as rnk
from dual
connect by level<=(select max(repeat) from t)
)
select job, quantity, status, repeat, rnk
from t join num on ( num.rnk <= repeat )
order by job, rnk;
Instead of doing this manipulation with query you can get this data first in a data table and add rows to a new data table based on the value of repeat and then bind this new data table.