I've got a table in my database which looks like this:
payment_id customer_id amount payment_date
1 32 20.00 2005-01-25 11:30:37
2 32 10.00 2005-01-26 11:30:37
3 11 25.00 2005-03-25 11:30:37
Now I want to sum all amounts a customer (customer_id) made in the respective month.
I need a query that looks which month exists and which customers have an entry for this month.
The result should look like this:
customer_id month amount
32 01 30.00
11 03 25
I tried this:
SELECT DISTINCT month(payment_date) AS month, customer_id, sum(amount) AS amount
FROM table
But it just sums all amount values of the whole table.
You have to use a GROUP BY query:
SELECT
customer_id,
month(payment_date) as month,
sum(amount) as total_amount
FROM
tablename
GROUP BY
customer_id,
month(payment_date)
Related
I have this query from Uploads table:
select
Costumer as Customer,
max(Week) as 'Max Week',
count(distinct(POS)) as 'Total POS'
from Uploads
where year = 2022
group by Costumer;
and returns this:
Customer
Max Week
Total POS
Customer A
3
65
Customer B
5
27
Customer C
3
33
This table has an additional column named Inventory and I want to know the SUM(Inventory) but with the weeks filtered before.
For example:
Customer
Max Week
Total POS
Inventory
Customer A
3
65
456
Customer B
5
27
123
Customer C
3
33
2345
You can solve this issue by using Row_Number like this
SELECT t.[Total POS],
t.customer,
t.week MaxWeek,
t.SumInventoryPerWeek SumForMaxWeek
FROM (
select
Costumer as Customer,
Week as week,
count(distinct(POS)) as 'Total POS',
SUM(Inventory) SumInventoryPerWeek,
ROW_NUMBER() OVER(PARTITION BY Costumer ORDER BY Week DESC) rw
from Uploads
where year = 2022
group by Costumer,Week
) t
WHERE t.rw=1
I have an orders table
Order_id User_id Order_date
1 32 2020-07-19
2 24 2020-07-21
3 27 2020-07-27
4 24 2020-08-14
5 32 2020-08-18
6 32 2020-08-19
7 58 2020-08-20
Now I want to find how many of the users ordered in 1st month also ordered in the next month. In this case, user_id's 32,24,27 ordered in 7th month but only 24 and 32 ordered in the next month.
I want the result to be like :
Date Retained_Users Total_users
2020-07 Null 3
2020-08 2 3
I'm lost here. Can someone please help me with this?
In MySQL 8.0, you can do this with window functions:
select
order_month,
count(distinct case when cnt_orders_last_month > 0 then user_id end) retained_users,
count(distinct user_id) total_users
from (
select
user_id,
date_format(order_date, '%Y-%m-01') as order_month,
count(*) over(
partition by user_id
order by date(date_format(order_date, '%Y-%m-01'))
range between interval 1 month preceding and interval 1 day preceding
) cnt_orders_last_month
from mytable
) t
group by order_month
The logic lies in the range specification of the window function; it orders record by month, and counts how many orders the customer placed last month. Then all that is left to do is aggregate and count distinct users.
Demo on DB Fiddle
I have a table with the following structure and sample data:
STORE_ID | INS_TIME | TOTAL_AMOUNT
2 07:46:01 20
3 19:20:05 100
4 12:40:21 87
5 09:05:08 5
6 11:30:00 12
6 14:22:07 100
I need to get the hourly sum of TOTAL_AMOUNT for each STORE_ID.
I tried the following query but i don't know if it's correct.
SELECT STORE_ID, SUM(TOTAL_AMOUNT) , HOUR(INS_TIME) as HOUR FROM VENDAS201302
WHERE MINUTE(INS_TIME) <=59
GROUP BY HOUR,STORE_ID
ORDER BY INS_TIME;
Not sure why you are not considering different days here. You could get the hourly sum using Datepart() function as below in Sql-Server:
DEMO
SELECT STORE_ID, SUM(TOTAL_AMOUNT) HOURLY_SUM
FROM t1
GROUP BY STORE_ID, datepart(hour,convert(datetime,INS_TIME))
ORDER BY STORE_ID
SELECT STORE_ID,
HOUR(INS_TIME) as HOUR_OF_TIME,
SUM(TOTAL_AMOUNT) as AMOUNT_SUM
FROM VENDAS201302
GROUP BY STORE_ID, HOUR_OF_TIME
ORDER BY INS_TIME;
I have a table that shows , for each date, a list of customer ids - shows customers who were active on any particular day. So each date can include ids that are also present in another date.
bdate customer_id
2012-01-12 111
2012-01-13 222
2012-01-13 333
2012-01-14 111
2012-01-14 333
2012-01-14 666
2012-01-14 777
I am looking to write a query which calculates the total number of unique ids between two dates - the starting date is the row date and the ending date is a particular date in the future.
My query looks like this:
select
bdate,
count(distinct customer_id) as cts
from users
where bdate between bdate and current_date
group by 1
order by 1
But this produces a count of unique users for each date like this:
bdate customer_id
2012-01-12 1
2012-01-13 2
2012-01-14 4
my desired result is ( for a count of users between starting row date and 2012-01-14 )
bdate customer_id
2012-01-12 5 - includes (111,222,333,666,777)
2012-01-13 5 - includes (222,333,111,666,777)
2012-01-14 4 - includes (111,333,666,777)
Like #Strawberry said, you can make a join like this:
select
t1.bdate,
count(distinct t2.customer_id) as cts
from users t1
join users t2 on t2.bdate >= t1.bdate
where t1.bdate between t1.bdate and current_date
group by t1.bdate
order by t1.bdate
join t2 can get you all the users between particular day and current_date, then count t2's customer_id, that's it.
SqlFiddle Demo Here
I have a cron script that writes the total number of active users to a table every day. I'm trying to now generate a simple report that would show the "high water mark" for each month. Because some accounts expire during the month it's possible the highest number may NOT be at the end of the month.
Here's a sample of my table structure
tblUserLog
-----------
record_id INT(11) // PRIMARY KEY
run_date DATE // DATE RUN
ttl_count INT(11) // TOTAL FOR DAY
Sample data:
record_id run_date ttl_count
1 2013-06-01 500
2 2013-06-10 510
3 2013-06-20 520
4 2013-06-30 515
5 2013-07-01 525
6 2013-07-10 530
7 2013-07-20 540
8 2013-07-31 550
9 2013-08-01 560
What I would like returned is:
record_id run_date ttl_count
3 2013-06-20 520
8 2013-07-31 550
9 2013-08-01 560
I've tried two queries that are close...
// This will give me the total for the first of the month
SELECT s.record_id, s.run_date, s.ttl_count
FROM tblStatsIndividual s
JOIN (
SELECT record_id
FROM tblStatsIndividual
GROUP BY DATE_FORMAT(run_date, '%Y %m')
HAVING MAX(ttl_count)
) s2
ON s2.record_id = s.record_id
ORDER BY run_date DESC
This returns the total for the first of each month, along with the record_id and correct date for the total.
Tried this...
SELECT record_id,max(run_date), max(ttl)
FROM (
SELECT record_id,run_date, max(ttl_count) AS ttl
FROM tblStatsIndividual
GROUP BY DATE_FORMAT(run_date, '%Y %m')
) a
GROUP BY DATE_FORMAT(run_date, '%Y %m')
ORDER BY run_date DESC
This one appears to get the correct "high water mark" but it's not returning the record_id, or the run_date for the row that IS the high water mark.
How do you get the record_id and the run_date for the highest total?
Something like
Select detail.Record_ID, detail.Run_Date, detail.ttl_Count
From tblStatsIndividual detail
Inner Join
(Select Year(run_date) as Year, Month(Run_date) as Month, Max(ttl_count) as ttl
From tblStatsIndividual
Group By Year(run_date), Month(Run_date)) maximums
On maximums.Year = Year(detail.Run_date) and maximums.Month = Month(detail.Run_date)
and maximums.ttl = detail.ttl_count
Should do it. NB based on your requirement if you had two records in the same month with the same (and highest in the month) ttl_count, they would both be returned.
Based on the help from #Tony Hopkinson, This query gets me the info. The one caveat is it shows the ID and date for the first occurrence of the MAX total, so if the total is the same three days in a row on a month, the first day's ID is returned. For my purpose, the last ID would be more ideal, but I can live with this:
SELECT s.Record_ID, s.Run_Date, s.ttl_Count
FROM tblStatsIndividual s
INNER JOIN (
SELECT YEAR(run_date) AS yr, MONTH(run_date) AS mon, MAX(ttl_count) AS ttl
FROM tblStatsIndividual
GROUP BY DATE_FORMAT(run_date, '%Y %m')
) maximums
ON maximums.yr = YEAR(s.run_date)
AND maximums.mon = MONTH(s.run_date)
AND maximums.ttl = s.ttl_Count
GROUP BY ttl_count
ORDER BY run_date DESC