how can I change where value in postgresql? - 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

Related

KDB+: How to retrieve the rows immediately before and after a given row that conform to a specific logic?

Given the following table
time kind counter key1 value
----------------------------------------
1 1 1 1 1
2 0 1 1 2
3 0 1 2 3
5 0 1 1 4
5 1 2 2 5
6 0 2 3 6
7 0 2 2 7
8 1 3 3 8
9 1 4 3 9
How would one select the value in the first row
immediately after and immediately before each
row of kind 1 ordered by time where the key1
value is the same in both instances .i.e:
time value prevvalue nextvalue
---------------------------------------------
1 1 0n 2
5 5 3 7
8 8 6 0n
9 9 6 0n
Here are some of the things I have tried, though
to be honest I have no idea how to canonically achieve
something like this in q whereby the prior value has a
variable offset to the current row?
select
prev[value],
next[value],
by key1 where kind<>1
update 0N^prevval,0N^nextval from update prevval:prev value1,nextval:next value1 by key1 from table
Some advice or a pointer on how to achieve this would be great!
Thanks
I was able to use the following code to return a table meeting your requirements. If this is correct, the sample table you have provided is incorrect, otherwise I have misunderstood the question.
q)table:([] time:1 2 3 5 5 6 7 8 9;kind:1 0 0 0 1 0 0 1 1;counter:1 1 1 1 2 2 2 3 4;key1:1 1 2 1 2 3 2 3 3;value1:1 2 3 4 5 6 7 8 9)
q)tab2:update 0N^prevval,0N^nextval from update prevval:prev value1,nextval:next value1 by key1 from table
q)tab3:select from tab2 where kind=1
time value1 prevval nextval
---------------------------
1 1 2
5 5 3 7
8 8 6 9
9 9 8
The update statement in tab2:
update 0N^prevval,0N^nextval from update prevval:prev value1,nextval:next value1 by key1 from table
is simply adding 2 columns onto the original table with the previous and next values for each row. 0^ is filling the empty fields with nulls.
The select statement in tab3:
tab3:select from tab2 where kind=1
is filtering tab2 for rows where kind=1.
The final select statement:
select time,value1,prevval,nextval from tab3
is selecting the rows you want to be returned in the final result.
Hope this answers your question.
Thanks,
Caitlin

Query to Get all Row Combinations

I want a query to retrive all row combinations from the below data set
This is my original Dataset.
SId Sequence RId
2976 1 100
4576 1 100
19472 1 100
80591 1 100
58811 1 100
70859 1 100
170941 2 100
167578 2 100
131885 2 100
117608 2 100
78117 1 101
69481 1 101
70987 2 101
46857 2 101
28396 2 101
From this data set I want the result based on RId and combination of each sequence of 1 and 2.
So For the above case for RId 100 there should be 24 combinations like
the below data:
RSId Sid Sequence RId
1 2976 1 100
1 170941 2 100
2 2976 1 100
2 167578 2 100
3 2976 1 100
3 131885 2 100
the below is the input table format
CREATE TABLE #temp ( SId INT,Sequence INT,Rid INT)
INSERT into #temp values (2976,1,100)
insert into #temp values (4576,1,100)
insert into #temp values (19472,1,100)
insert into #temp values (80591,1,100)
insert into #temp values (58811,1,100)
insert into #temp values (70859,1,100)
insert into #temp values (170941,2,100)
insert into #temp values (167578,2,100)
insert into #temp values (131885,2,100)
insert into #temp values (117608,2,100)
insert into #temp values (78117,1,101)
insert into #temp values (69481,1,101)
insert into #temp values (70987,2,101)
insert into #temp values (46857,2,101)
insert into #temp values (28396,2,101)
SELECT * FROM #Temp
the result should be of the below table format:
RSId Sid Sequence RId
1 2976 1 100
1 170941 2 100
2 2976 1 100
2 167578 2 100
3 2976 1 100
3 131885 2 100
4 2976 1 100
4 117608 2 100
5 4576 1 100
5 170941 2 100
6 4576 1 100
6 167578 2 100
7 4576 1 100
7 131885 2 100
8 4576 1 100
8 117608 2 100
9 19472 1 100
9 170941 2 100
10 19472 1 100
10 167578 2 100
11 19472 1 100
11 131885 2 100
12 19472 1 100
12 117608 2 100
13 80591 1 100
13 170941 2 100
14 80591 1 100
14 167578 2 100
15 80591 1 100
15 131885 2 100
16 80591 1 100
16 117608 2 100
17 58811 1 100
17 170941 2 100
18 58811 1 100
18 167578 2 100
19 58811 1 100
19 131885 2 100
20 58811 1 100
20 117608 2 100
21 70859 1 100
21 117608 2 100
22 70859 1 100
22 170941 2 100
23 70859 1 100
23 167578 2 100
24 70859 1 100
24 131885 2 100
One way to do it is to use common table expressions, cross join and union.
It might be a bit cumbersome but it should have pretty good performance:
DECLARE #Rid int = 100;
With cte1 As
(
SELECT SID, Sequence, Rid
FROM #Temp
WHERE Sequence = 1
AND Rid = #Rid
), cte2 AS
(
SELECT SID, Sequence, Rid
FROM #Temp
WHERE Sequence = 2
AND Rid = #Rid
), cteCJ AS
(
SELECT Cte1.Sid As Sid1, Cte1.Sequence As Seq1, Cte1.Rid As Rid,
Cte2.Sid As Sid2, Cte2.Sequence As Seq2,
ROW_NUMBER() OVER(ORDER BY Cte1.Sid) As RSId
FROM Cte1
CROSS JOIN Cte2
)
SELECT RSId, Sid1 As Sid, Seq1 As Sequence, Rid
FROM cteCJ
UNION
SELECT RSId, sid2, Seq2, Rid
FROM cteCJ
ORDER BY RSId, Seq1
Results:
RSId Sid Sequence Rid
1 2976 1 100
1 170941 2 100
2 2976 1 100
2 167578 2 100
3 2976 1 100
3 131885 2 100
4 2976 1 100
4 117608 2 100
5 4576 1 100
5 170941 2 100
6 4576 1 100
6 167578 2 100
7 4576 1 100
7 131885 2 100
8 4576 1 100
8 117608 2 100
9 19472 1 100
9 170941 2 100
10 19472 1 100
10 167578 2 100
11 19472 1 100
11 131885 2 100
12 19472 1 100
12 117608 2 100
13 58811 1 100
13 170941 2 100
14 58811 1 100
14 167578 2 100
15 58811 1 100
15 131885 2 100
16 58811 1 100
16 117608 2 100
17 70859 1 100
17 170941 2 100
18 70859 1 100
18 167578 2 100
19 70859 1 100
19 131885 2 100
20 70859 1 100
20 117608 2 100
21 80591 1 100
21 170941 2 100
22 80591 1 100
22 167578 2 100
23 80591 1 100
23 131885 2 100
24 80591 1 100
24 117608 2 100

spreading the days and the number of repetitions of each person for each specific day in postgresql

i have this table in postgresql database
id name time
1 poi 2018-05-13 08:45:48.846887
2 poi 2018-05-13 08:11:04.671437
3 roik 2018-05-14 16:32:04.671437
4 ceil 2018-05-14 17:38:04.671437
5 verk 2018-05-14 19:46:04.671437
6 roik 2018-05-16 08:21:04.671437
7 poi 2018-05-16 11:00:04.671437
8 roik 2018-05-18 14:40:08.671437
9 roik 2018-05-18 17:21:09.671664
10 verk 2018-05-13 08:46:04.671437
11 sant ...
12 sant ...
13 dmk ...
14 roik ...
15 poi ...
... .... ...
I want to have such a table:
name 2018-5-1 2018-5-2 2018-5-3 2018-5-4 2018-5-5 2018-5-6 2018-5-7 2018-5-8 2018-5-9 2018-5-10 2018-5-11 2018-5-12 2018-5-13 2018-5-14 ...
poi 0 3 3 7
roik 0 4 2 1
verk 0 2 0 9
sant 1 0 8 2
dmk 0 3 ...
...
These numbers represent the number of repetitions of each person for each particular day
how can i do this??thank you in advance
This is not exactly what you want but very similar to. You just need to translate "date" colun values to a columns itself, but you can easily do it on client after you queried the dates you need.
https://www.db-fiddle.com/f/7r4AG9MV9zeZEjoU77fCfk/2
SELECT Test.name, SUM(CASE WHEN date(Test.time) = dates.date THEN 1 ELSE 0 END), dates.date FROM Test CROSS JOIN
(SELECT DISTINCT(date(time)) as date FROM Test) as dates
GROUP BY Test.name, dates.date

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.

Recursive Cumulative Sum up to a certain value Postgres

I have my data that looks like this:
user_id touchpoint_number days_difference
1 1 5
1 2 20
1 3 25
1 4 10
2 1 2
2 2 30
2 3 4
I would like to create one more column that would create a cumulative sum of the days_difference, partitioned by user_id, but would reset whenever the value reaches 30 and starts counting from 0. I have been trying to do it, but I couldn't figure it out how to do it in PostgreSQL, because it has to be recursive.
The outcome I would like to have would be something like:
user_id touchpoint_number days_difference cum_sum_upto30
1 1 5 5
1 2 20 25
1 3 25 0 --- new count all over again
1 4 10 10
2 1 2 2
2 2 30 0 --- new count all over again
2 3 4 4
Do you have any cool ideas how this could be done?
This should do what you want:
with cte as (
select t.a, t.b, t.c, t.c as sumc
from t
where b = 1
union all
select t.a, t.b, t.c,
(case when t.c + cte.sumc > 30 then 0 else t.c + cte.sumc end)
from t join
cte
on t.b = cte.b + 1 and t.a = cte.a
)
select *
from cte
order by a, b;
Here is a rextester.