Conditional counting and summation in SQL - aggregate

I have this raw table below. What I would like to do is conditionally count the number of reviews based upon the 3 'hit types'.
Reviewer date id 3_hit 2_hit 1_hit
jack 1 Sep 1 TRUE FALSE FALSE
jack 1 Sep 1 FALSE TRUE FALSE
jack 1 Sep 3 TRUE FALSE FALSE
jack 1 Sep 4 FALSE TRUE FALSE
jack 1 Sep 5 FALSE TRUE FALSE
tim 2 Sep 6 TRUE FALSE FALSE
tim 2 Sep 7 FALSE FALSE TRUE
There are 3 conditions I would like to query on:
If an id is TRUE for 3_hit AND also has TRUE for either 2_hit or 1_hit in another row, then count as 1 "3_hit".
If an id is TRUE for 2_hit, but also as TRUE for 1_hit in another row, then count as 1 "2_hit".
If an id is TRUE for 1_hit, and FALSE for 2_hit and 3_hit, then count as 1 "1_hit".
*note, pretend the 1st table has the timestamp in the date field (not just the date)
Reviewer date type r_count max time min time time_h
jack 1 Sep 3_hit 2 7:00 PM 1:00 PM 6
jack 1 Sep 2_hit 2 5:00 PM 1:00 PM 4
tim 2 Sep 3_hit 1 5:00 PM 1:00 PM 4
tim 2 Sep 1_hit 1 3:00 PM 1:00 PM 2
I would then like to be able to get the time per review for each type, it would look as follows:
reviewer date review type r_count reviews/hour
jack 1 Sep 3_hit 2 2/6
jack 1 Sep 2_hit 2 2/4
tim 2 Sep 3_hit 1 2/4
tim 2 Sep 1_hit 1 1/2
I know this will require a few levels of aggregation, which is fine. The most important thing is that the last table is filterable using Looker, so that I can filter by review type and date.
I'm not sure this is possible in SQL, but I can't figure out how to simulate a new column and then count based on how many results are in that column. Is this possible? I guess it would be a pivot of sorts.
Note I also realize that the reviews per hour won't exactly be accurate, as there will be overlap in time taken to review different reviews. Unfortunately, this date/time is the best I have to do this kind of analysis.
Would appreciate any and all help on this! Thanks!

Related

missing years - replace with empty row

I am tying to retrieve some data and it is as below:
id
year
value
1
2015
200
1
2016
3000
1
2018
500
2
2010
455
2
2015
678
2
2020
100
as you can see some years are missing - I would like to add the rows with missing years, null for column value and I want to do it per specific ids - any ideas?
You can combine GENERATE_SERIES() with a left join do expand the missing years. For example:
select x.id, x.y, t.value
from (select id, generate_series(min(year), max(year)) as y from t group by id) x
left join t on t.id = x.id and t.year = x.y
Result:
id y value
--- ----- -----
1 2015 200
1 2016 3000
1 2017 null
1 2018 500
2 2010 455
2 2011 null
2 2012 null
2 2013 null
2 2014 null
2 2015 678
2 2016 null
2 2017 null
2 2018 null
2 2019 null
2 2020 100

How to dynamic calculate value using formulas in postgresql

I'm in new this field. How do I manage the dynamic calculation with formulas and what steps to achieve the below output?.
I have tables.
Table 1 - Info_question table is for details about questions name and id.
q_id
questions_name
1
A
2
B
3
C
4
D
Table 2 - data_question is for data values.
id
q_id
period
data_value
1
1
2022
1000
2
1
2021
2000
3
2
2022
3000
4
3
2022
4000
5
4
2022
5000
I need to calculate A+B+C and that output will insert into data_question table and new question will create in the info_question table.(formulas will change for new question like A/B*100 or A+C and question id will be new generate)
For (A+B+C) Output should be shows like below tables.
data_question table
id
q_id
period
data_value
1
1
2022
1000
2
1
2021
2000
3
2
2022
3000
4
3
2022
4000
5
4
2022
5000
6
5
2022
8000
7
5
2021
2000
and info_question
q_id
questions_name
1
A
2
B
3
C
4
D
5
E

How to count finished courses into 1 and count all those who finished the training

I have 5 mandatory courses which is [ Python, Java, Kotlin, SQL, React ]. And I have different tables
Table name : dbo.course
course_id
course_name
mandatory
category_id
1
python
yes
20
2
java
yes
20
3
kotlin
yes
20
4
sql
yes
20
5
react
yes
20
6
c++
no
21
7
git
no
22
8
vb.net
no
23
table name : Table name : dbo.category which is linked to dbo.course
category_id
category_name
20
Dev
21
Bridge
22
PM
23
Bas
Table name : dbo.attendance (p = present , a = absent)
participant_id
status
course_id
log_in_date
log_out_date
1
p
1
july 2021
july 2021
1
p
2
july 2021
july 2021
1
p
3
july 2021
july 2021
1
p
4
july 2021
july 2021
1
p
5
july 2021
july 2021
2
p
1
july 2021
july 2021
3
a
6
null
null
4
a
8
null
null
5
p
1
july 2021
july 2021
5
p
2
july 2021
july 2021
5
p
3
july 2021
july 2021
5
p
4
july 2021
july 2021
5
p
5
july 2021
july 2021
if the participant finished all the mandatory courses then it will count as 1 and if not, it will not count unless he/she finish the training. I want the output something like this : Assume that there is 5 participant that finished the training in August 2021 and 10 participant in September 2021
select date,count(participant), count(*)
date
participant
count
july 2021
2
2
august 2021
5
7
september 2021
10
17

PostgreSQL - How can I SUM until a certain hour of the day?

I'm trying to create a metric for a PostgreSQL integrated dashboard which would show today's "Total Payment Value" (TPV) of a certain product, as well as yesterday's TPV of the same product, up until the same moment as today, so if I'm accessing the dashboard at 5 pm, it will show what it was yesterday until 5 pm and today's TPV.
edit: My question wasn't very clear so I'm adding a few more lines and editing the query, which had a mistake.
I tried this:
select
sum(case when table.product in (13,14,15,16) then amount else 0 end) as "TPV"
,date_trunc('day', table.date) as "Day"
from table
where
date > current_date - 1
group by date_trunc('day', table.date)
order by 2,1
I only want to sum the amount when product = 13, 14, 15 or 16
An example of the product, date and amount would be like this:
product amount date
8 4750 19/03/2019 00:21
14 7840 12/04/2019 22:40
14 15000 22/03/2019 18:27
14 11715 19/03/2019 00:12
14 1054 22/03/2019 18:22
14 18491 17/03/2019 14:28
14 12253 17/03/2019 14:30
14 27600 17/03/2019 14:32
14 3936 17/03/2019 14:28
14 19007 19/03/2019 00:14
8 9400 19/03/2019 00:21
8 4750 19/03/2019 00:21
8 25000 19/03/2019 00:17
14 10346 22/03/2019 18:23
I would like to have a metric that always calculates the sum of the product value today up until the current moment - when the "product" corresponds to values 13, 14, 15 or 16 - as well as the same metric for yesterday, e.g., it's 1 PM now, I want today's TPV until 1 PM and yesterday's TPV until 1 PM as well!

Calculating Running Avg for YTD Sum with constant denominator for a year

I have the following table from SQL
ID Date Score
-----+-------------+----------
10 2015-01-10 5
20 2015-01-10 5
10 2015-02-10 15
40 2015-02-10 25
30 2015-02-10 5
10 2015-03-10 15
10 2014-01-10 25
20 2014-02-10 35
50 2014-03-10 45
In Tableau I want a line graph to display
(YTD Sum of Score)/Total number of IDs for a year.
For Jan 2015 - 10/4=2.5
For Feb 2015 - 55/4=13.75
For Jan 2014 - 60/3=20
The denominator should remain constant throughout the year and not change monthwise.
Looks like you can achieve your desired result with two calculated fields. First, make a [Year] field with:
year([Date])
Then make a second calculated field as follows:
sum([Score])/sum({fixed [Year] : countd([Id])})
This will sum the score and divide by IDs for the given year. It uses Level of Detail calculation.