postgres find age range with no of minutes of different user to watch channels - postgresql

I have two table 1000 of record given below.
My first table is USER table.
ID Name DateOfBirth
1 John 1980-11-20 00:00:00.000
2 Denial 1940-04-10 00:00:00.000
3 Binney 1995-12-25 00:00:00.000
4 Sara 1960-11-20 00:00:00.000
5 Poma 1980-11-20 00:00:00.000
6 Cameroon 1980-11-20 00:00:00.000
.....
.....
And my second table is CHANNEL_WATCH_DURATION_BY_USER
userid duration channelname
1 100 SAB
2 200 zee Tv
1 400 axn
2 0 star 1
3 800 star 2
3 700 star 3
4 200 star 4
.....
.....
I need to write the POSTGRES SQL Query to display different age groups contain duration with each channel.
under 18 20-30 age 30-40 age chaneel
10 40 100 star 1
20 0 200 star 2
30 79 0 zee
40 80 30 axn
.....
.....

SELECT
SUM(IF(DATEDIFF(NOW(),DateOfBirth)<18,1,0)) AS under18,
SUM(IF(DATEDIFF(NOW(),DateOfBirth) BETWEEN 20 AND 30,1,0)) as 20_to_30_age,
SUM(IF(DATEDIFF(NOW(),DateOfBirth)BETWEEN 30 AND 40,1,0)) as 30_to_40_age,
channelname as chaneel from
USER a,CHANNEL_WATCH_DURATION_BY_USER b where a.ID=b.USERID GROUP BY channelname

Related

How to calculate the amount spent for the last month in SQL?

I have a table transaction_details:
transaction_id
customer_id
item_id
item_number
transaction_dttm
7765
1
23
1
2022-01-15
1254
2
12
4
2022-02-03
3332
3
56
2
2022-02-15
7658
1
43
1
2022-03-01
7231
4
56
1
2022-01-15
7231
2
23
2
2022-01-29
I need to form a table of the following type customer_aggr:
customer_id
amount_spent_lm
top_item_lm
1
700
glasses
2
20000
notebook
3
100
cup
When calculating, it is necessary to take into account the current price at the time of the transaction (dict_item_prices). Customers who have not made purchases in the last month are not included in the final table. he last month is defined as the last 30 days at the time of the report creation.
There is also a table dict_item_prices:
item_id
item_name
item_price
valid_from_dt
valid_to_dt
23
phone 1
1000
2022-01-01
2022-12-31
12
notebook
5000
2022-01-02
2022-12-31
56
cup
50
2022-01-02
2022-12-31
43
glasses
700
2022-01-01
2022-12-31

Pandas's `pct_change()` equivalent in postgres

Let's assume I have a table like this:
id
date
value
1
2021-04-05
100
1
2021-04-04
50
1
2021-04-03
25
1
2021-04-02
5
2
2021-04-05
80
2
2021-04-04
20
2
2021-04-03
15
2
2021-04-02
10
I need to add another column that groups by id and calculates a day-over-day percent change from the value with the date before it. So for this example it would look like this:
id
date
value
pct_change
1
2021-04-05
100
100
1
2021-04-04
50
100
1
2021-04-03
25
400
1
2021-04-02
5
NaN
2
2021-04-05
80
300
2
2021-04-04
20
33.33
2
2021-04-03
15
50
2
2021-04-02
10
NaN
In python this would be easy, I could do something like this:
df['pct_change'] = df.groupby('id').value.pct_change() * 100
But if I wanted to do this in the Postgres database call, I'd suddenly implode with stupidity... does anybody know how to do this?
Maybe something like this?
SELECT
id,
date,
value,
(value - prev_value) / prev_value AS pct_change
FROM
(
SELECT
id,
date,
value,
LAG(value) OVER (PARTITION BY id ORDER BY date
ROWS BETWEEN 1 PRECEDING AND
CURRENT ROW) AS prev_value
FROM
your_table
)
ORDER BY date, id

T_SQL counting particular values in one row with multiple columns

I have little problem with counting cells with particular value in one row in MSSMS.
Table looks like
ID
Month
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
11
12
13
14
15
16
...
31
5000
1
null
null
1
1
null
1
1
null
null
2
2
2
2
2
null
null
3
3
3
3
3
null
...
1
I need to count how many cells in one row have value for example 1. In this case it would be 5.
Data represents worker shifts in a month. Be aware that there is a column named month (FK with values 1-12), i don't want to count that in a result.
Column ID is ALWAYS 4 digit number.
Possibility is to use count(case when) but in examples there are only two or three columns not 31. Statement will be very long. Is there any other option to count it?
Thanks for any advices.
I'm going to strongly suggest that you abandon your current table design, and instead store one day per month, per record, not column. That is, use this design:
ID | Date | Value
5000 | 2021-01-01 | NULL
5000 | 2021-01-02 | NULL
5000 | 2021-01-03 | 1
5000 | 2021-01-04 | 1
5000 | 2021-01-05 | NULL
...
5000 | 2021-01-31 | 5
Then use this query:
SELECT
ID,
CONVERT(varchar(7), Date, 120),
COUNT(CASE WHEN Value = 1 THEN 1 END) AS one_cnt
FROM yourTable
GROUP BY
ID,
CONVERT(varchar(7), Date, 120);

TSQL - Max per group?

I have a table that looks like this:
GroupID UserID Value
1 1 10
1 2 20
1 3 30
1 4 40
1 5 45
1 6 49
1 7 80
1 8 90
2 1 2
2 2 24
2 3 34
2 4 48
2 5 56
3 1 etc.
3 2
3 3
3 4
4 1
4 2
4 3
I am trying to write a LEAD function that will give me the midpoint between each value. To do this I have written the following:
SELECT
[GroupID]
, [UserID]+0.5
, (LEAD ([Value], 1) OVER (ORDER BY GroupID, UserID) + [Value])/2 as [Value]
from dbo.myTable
The problem with this function is that when it gets to the last User in the group, it gives me a bad value because it's taking the [Value] on the current row and the value from the next row.
What I want to do is stop it when it reaches the maximum UserID for each Group. In other words, when it gets to GroupID = 1 and UserID = 8, it should end and start at the next Group. I do not want a row that looks like this:
GroupID UserID Value
1 8.5 46
I could run a DELETE statement after I INSERT the rows into the original table, but I don't have anything to identify when a row is the "maximum" User for it's Group. Ideally, I would like to somehow tell the lead statement not to calculate it in the first place.

how can I change where value in postgresql?

id o_num d_num
69af4bf986c4df522afb54da6512bdc5 5 5
69af6111de53b550b0d13f86398b59e5 19 19
69b264c4b93a1984450689b16807b293 10 10
69b26c0fb38ff1cd2d4b01696aa14883 20 20
69b5c46bdc8a8f49f913d9d2325f0a76 15 15
69b71276a69dece5630ed3405ceca411 1 6
69b790c7937602e8fd52bc4d28194625 5 17
69b7bfde4effdaf31d362165a23a8dd0 4 13
69b93626a799636aef2ab3567cf3a110 14 14
I have a table like this, there are total 20 o_num in the table, and i want to select all the row that o_num is 1 then group by the d_num to count the id number, and them change the o_num to 2, until o_num to 20. and the result is in one table.
here is my code for 1 time:
SELECT COUNT(id), o_num, d_num
FROM table1
WHERE o_num = 1
GROUP BY o_num, d_num
how can i change the code to get my table
I want get the reselt like this,a table with 3 columns
sum o_num d_num
9 1 1
8 1 2
4 1 3
……
5 1 20
4 2 1
6 2 2
8 2 3
……
3 2 20
5 3 1
……
……
2 20 20