I have running total
SELECT
id,
DepositValue,
action_date,
SUM(DepositValue) OVER(ORDER by action_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Running_total
The above select returns me the following:
id action_date DepositValue Running_total
1 2020-04-01 20 20
2 2020-04-02 2 22
3 2020-04-03 8 30
4 2020-04-04 10 38
5 2020-04-05 14 48
6 2020-04-06 15 62
7 2020-04-07 22 77
8 2020-04-08 12 99
9 2020-04-09 4 103
What i want to achieve is selecting only part of Running_total depend on action_date with already calculated values like this.
id action_date DepositValue Running_total
3 2020-04-03 8 30
4 2020-04-04 10 38
5 2020-04-05 14 48
You can turn your query to a subquery and filter in the outer query:
SELECT *
FROM (
SELECT
id,
DepositValue ,
action_date,
SUM(DepositValue) OVER(ORDER by action_date) AS Running_total
FROM mytable
) t
WHERE action_date BETWEEN '2020-04-03' AND '2020-04-05'
Note that window specification ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW is actually the default when not specificed, hence you can just remove it.
Also, your original query was missing a FROM clause, I added it.
Related
Hello i have a table with some ids and values
for example:
SELECT instrumentid, value from `mytable` where instrumentid in (12,11, 14,15);
id, instrumentid, recorddate, value
33 12 2022-10-05 55
34 11 2022-10-05 33
30 14 2022-10-05 13
29 12 2022-10-03 12
28 11 2022-10-03 53
40 14 2022-10-03 4
44 15 2022-10-03 4
as result i want or better explained only the last newst entry for instrumentid
instrumentid, value
12 55
11 33
14 13
15 4
thanks and regards
running latest mariadb 10.9.3
You can use ROW_NUMBER() to identify the last row for each instrument.
For example:
select *
from (
select t.*,
row_number() over(partition by instrumentit order by recorddate desc) as rn
from mytable t
where instrumentid in (12,11, 14,15)
) x
where rn = 1
Table "users":
id
name
email
created_at
46
FSDSD2
FSDSD2#thebluedot.co
2022-05-29 14:19:21
47
Fxz3
Fxz3#gmail.com
2022-05-30 20:12:15
48
Fgh3
Fgh3#gmail.com
2022-05-31 20:12:15
49
Fghxc3
Fghxc3#gmail.com
2022-06-01 20:12:15
50
Fdx3
Fdx3#gmail.com
2022-06-02 20:12:15
51
Fg3q3
Fg3q3#gmail.com
2022-06-03 20:12:15
88
Fbhgt
Fbhgt#gmail.co
2022-05-23 16:38:41
112
Fht
Fht#gmail.com
2022-05-24 16:19:23
113
Y14gss
Y14gss#gmail.com
2022-05-25 16:42:44
114
sfhf
sfhf#gmail.com
2022-05-26 12:10:40
115
A2czu
A2czu#thebluedot.co
2022-05-27 14:00:31
116
Cc1sn
Cc1sn#gmail.com
2022-05-28 12:04:56
Table "oxygen_point_earns":
id
user_id
oxygen_point
created_at
2
116
50.00
2022-05-23 17:49:30
3
113
10.00
2022-05-24 07:49:46
4
114
10.00
2022-05-25 07:50:42
5
46
50.00
2022-05-26 07:55:19
6
47
40.00
2022-05-27 13:28:17
7
48
30.00
2022-05-28 13:32:19
8
49
10.00
2022-05-29 13:32:19
9
50
5.00
2022-05-30 13:32:19
10
51
10.00
2022-05-31 13:32:19
11
88
20.00
2022-06-01 13:32:19
12
112
50.00
2022-06-02 13:32:19
13
115
10.00
2022-06-03 13:32:19
14
112
20.00
2022-06-03 16:32:19
I have two tables:
"users", which stores users basic information
"oxygen_point_earns", which stores oxygen points earned by specific users
The "users" table has 12 rows, though the "oxygen_point_earns" table contains 13 records, which means that one user can win points even more than once.
I was trying to made some calculation between those tables (e.g. dividing the total of weekly gained points by the weekly users cumulative sum, for each user). The problem occurs when I attempt to get the users cumulative sum.
SELECT STR_TO_DATE(CONCAT(YEARWEEK(op.created_at), ' Sunday'), '%X%V %W') AS week,
SUM(COUNT(*)) OVER(ORDER BY MIN(op.created_at)) AS user_count,
SUM(op.oxygen_point) AS op_weekly
FROM users us
LEFT JOIN oxygen_point_earns op
ON us.id = op.user_id
GROUP BY week
ORDER BY week
This query gets me the following output:
As you can see, even though the points are correctly computed, the total user count is wrong at the second row: it should be 12 instead of 13 (First week I got 6 users then next week 6 more users registered. So my total user count is 12. On second row I should get 12.)
I tried DISTINCT, GROUP_CONCAT but didn't work. How can I fix this query to get true result of users counts?
One straightforward option is to separate the two operations (aggregation and windowing) using a subquery/cte:
WITH cte AS (
SELECT STR_TO_DATE(CONCAT(YEARWEEK(op.created_at), ' Sunday'), '%X%V %W') AS week,
COUNT(DISTINCT user_id) AS cnt,
SUM(op.oxygen_point) AS op_weekly
FROM users us
LEFT JOIN oxygen_point_earns op ON us.id = op.user_id
GROUP BY week
)
SELECT week,
SUM(cnt) OVER(ORDER BY week) AS user_count,
op_weekly
FROM cte
ORDER BY week
Suppose we have a table like:
ID
Account
Amount
Date
1
4455
52
01-01-2022
2
4455
32
02-01-2022
3
4455
23
03-01-2022
4
4455
23
04-01-2022
5
6565
236
01-01-2022
6
6565
623
02-01-2022
7
6565
132
03-01-2022
8
2656
564
01-01-2022
9
2656
132
02-01-2022
We need to retrieve every last row of given account_no. We need output like:
ID
Account
Amount
Date
4
4455
23
04-01-2022
7
6565
132
03-01-2022
10
2656
13
03-01-2022
Kindly suggest me a query to retrieve data like this in table of 2000 records.
You want the last row of certain query. So you must be having an order by clause. Just reverse the ordering and use a limit clause with limit set to one row.
SELECT column_name(s)
FROM table_name
WHERE condition
order by your_reversed_orderby_clause
LIMIT 1;
If you are using MySQL 8, then you can use ROW_NUMBER() function for this:
WITH CTE AS
(
SELECT ID,Account,Amount,Date
,ROW_NUMBER() OVER(PARTITION BY Account ORDER BY ID DESC) AS RN
FROM Table1
)
SELECT * FROM CTE
WHERE RN=1
ORDER BY ID;
ID
Account
Amount
Date
RN
4
4455
23
2022-04-01 00:00:00
1
7
6565
132
2022-03-01 00:00:00
1
9
2656
132
2022-02-01 00:00:00
1
See this db<>fiddle
SELECT * FROM table_name
WHERE ID IN (
SELECT max(ID) FROM table_name
GROUP BY Acount
ORDER BY Account
)
I am trying to attain the count of users that ordered at least 1 product on multiple days.
Transactions Table
usr_id|transt_id|product_id|spend| transaction_date
4 8 32 40 2020-05-08 17:54:59
4 7 31 20 2020-05-01 17:54:59
4 7 31 40 2020-05-01 17:54:59
4 6 20 30 2020-05-02 17:54:59
4 6 19 20 2020-05-02 17:54:59
4 6 18 10 2020-05-02 17:54:59
3 5 17 20 2020-05-04 17:54:59
3 5 16 10 2020-05-04 17:54:59
2 3 14 30 2020-05-04 18:54:59
2 3 13 50 2020-05-04 18:54:59
1 2 12 30 2020-05-05 20:54:59
1 2 12 40 2020-05-05 20:54:59
1 2 12 40 2020-05-04 20:54:59
1 1 11 20 2020-05-05 21:54:59
1 1 10 40 2020-05-05 21:54:59
3 4 10 60 2020-05-06 17:54:59
Through my code I have been able to reach to a point where the output is:
select user_id, count(*)
from (
select user_id, date(transaction_date)
from transactions
group by user_id, date(transaction_date)) as abc
group by user_id
having count(user_id)>1;
user_id | count
1 2
3 2
4 3
I want to write a code without writing another subquery to get the count of users having count(*)>1;
The output should be: 3.
In other words, I don't want the following code; I want to write one less subquery or a completely new query
select count(*)
from (
select user_id, count(*)
from (
select user_id, date(transaction_date)
from transactions
group by user_id, date(transaction_date)) as abc
group by user_id
having count(user_id)>1) as bcd;
The query that you already have could be written without a subquery:
select user_id, count(distinct date(transaction_date)) count
from transactions
group by user_id
having count(distinct date(transaction_date))>1;
So what you need now can be written with only 1 subquery:
select count(*) count
from (
select user_id
from transactions
group by user_id
having count(distinct date(transaction_date))>1
) t
You can get the same result with EXISTS:
select count(distinct t.user_id) count
from transactions t
where exists (
select 1
from transactions
where user_id = t.user_id and date(transaction_date) <> date(t.transaction_date)
)
See the demo.
I'm learning HIVE these days and meet some problems...
I have a table called SAMPLE:
USER_ID PRODUCT_ID NUMBER
1 3 20
1 4 30
1 2 25
1 6 50
1 5 40
2 1 10
2 3 15
2 2 40
2 5 30
2 3 35
How can I use HIVE to group table by user_id and in each group order the records by DESC order of NUMBER and in each group I want to keep up to 3 records.
The result I want to have is like:
USER_ID PRODUCT_ID NUMBER(optional column)
1 6 50
1 5 40
1 4 30
2 2 40
2 3 35
2 5 30
or
USER_ID PRODUCT_IDs
1 [6,5,4]
2 [2,3,5]
Could someone help me ?..
Thanks very much!!!!!!!!!!!!!!!!
try this,
select user_id,product_id,number
from(
select user_id,product_id,number, ROW_NUMBER() over (Partition BY user_id) as RNUM
from (
select user_id, number,product_id
from SAMPLE
order by number desc
) t) t2
where RNUM <=3
output
1 6 50
1 5 40
1 4 30
2 2 40
2 3 35
2 5 30
hive version should be 0.11 or greater, may I know if your version is lower