I have a table storing weatherdata in 5min intervals.
Now I need result with total raindays grouped by Year like this:.
2010 100 raindays
2011 120 raindays
2013 90 raindays
This is my current query:
SELECT date, SUM(rain) FROM $tableName GROUP BY date HAVING SUM(rain) > 0";
as expected, this gives me following result:
2010-01-02 1.2 (mm)
2010-01-05 1.6 (mm)
2010-02-10 2.6 (mm)
How I have to change my query, to have this grouped by year(date) and counted days ?
Thanks all for your help
PM
You can group by YEAR(date), to sum the rain grouped by year. Then to count the number of days you can COUNT DISTINCT the days without the time part, using DATE(date) function.
SELECT YEAR(date), SUM(rain), COUNT(DISTINCT DATE(date)) days
FROM $tableName
WHERE rain>0
GROUP BY YEAR(date)
Please see fiddle here.
The following query might help you if you want to find maximum element is each group,
select
e.date, e.rain
from
TableName e
join
(select
date, MAX(rain) MS
from
TableName
group by date
Having rain > 0) m ON e.date = M.date and e.rain = m.rain
Related
My table is like this:
root_tstamp
userId
2022-01-26T00:13:24.725+00:00
d2212
2022-01-26T00:13:24.669+00:00
ad323
2022-01-26T00:13:24.629+00:00
adfae
2022-01-26T00:13:24.573+00:00
adfa3
2022-01-26T00:13:24.552+00:00
adfef
...
...
2021-01-26T00:12:24.725+00:00
d2212
2021-01-26T00:15:24.669+00:00
daddfe
2021-01-26T00:14:24.629+00:00
adfda
2021-01-26T00:12:24.573+00:00
466eff
2021-01-26T00:12:24.552+00:00
adfafe
I want to get the number of users in the current year and in previous year like below using SQL.
Date Users previous_year
2022-01-01 10 5
2022-01-02 20 15
The code is written as follows.
select CAST(root_tstamp as DATE) as Date,
count(DISTINCT userid) as users,
count(Distinct case when CAST(root_tstamp as DATE) = dateadd(MONTH,-12,CAST(root_tstamp as DATE)) then userid end) as previous_year
FROM table1
But it returns 0 for previous_year values.
How can I fix that?
Possible solution for SQL Server:
WITH cte AS ( SELECT 2022 [year]
UNION ALL
SELECT 2021 )
SELECT cte.[year],
COUNT(DISTINCT test.userId) current_users_amount,
COUNT(DISTINCT CASE WHEN YEAR(test.root_tstamp) < cte.[year]
THEN test.userId
END) previous_users_amount
FROM test
JOIN cte ON YEAR(test.root_tstamp) <= cte.[year]
GROUP BY cte.[year]
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=88b78aad9acd965bdbac4c85a0b81927
This query (for MySql) returns unique number of userids where the root_timestamp is in the current year, by day, and the number of unique userids for the same day last year. If there is no record for a day in the current year nothing will be displayed for that day. If there are rows for the current year, but no rows for the same day last year, then NULL will be shown for that lastyear column.
SELECT cast(ty.root_tstamp as date) as Dte,
COUNT(DISTINCT ty.userId) as users_this_day,
count(distinct lysd.userid) as users_sameday_lastyear
FROM test ty
left join
test lysd
on cast(lysd.root_tstamp as date)=date_add(cast(ty.root_tstamp as date), interval -1 year)
WHERE YEAR(ty.root_tstamp) = year(current_date())
GROUP BY Dte
If you wish to show output rows for calendar days even if there are no rows in current year and/or last year, then you also need a calendar table to be introduced (let's hope that it is not what you need)
I have a yearly list of sales of an item for the past 20 years.
the data is like this.
date ; sales value
2001-01-01 ; 423
2001-01-02 ; 152
2001-01-03 ; 162
2001-01-04 ; 172
.
.
.
I have a behavioral problem. I must find the five consecutive days where the sum of sales is maximum in a year, for each year, for the past 20 years. Then using the result i must analyse the spending pattern.
how can i get the 5 consecutive days whose sum is maximum in a year?
I must get it for all years with dates and sum of sales in those 5 days total value. Can anyone help me in my assignment, please?
TIA
Well, in MySQL 8+, you can use window functions. In earlier versions, a correlated subquery. That looks like:
select year(t.date),
max(next_5_days_sales),
substring_index(group_concat(date order by next_5_days_sales desc), ',', 1) as date_at_max
from (select t.*,
(select sum(t2.sales)
from t t2
where t2.date >= t.date and t2.date < t.date + interval 5 day
) as next_5_days_sales
from t
) t
group by year(t.date);
Notes:
You will need to reset the group_concat_max_len, because 1024 is probably not long enough for the intermediate result.
This allows the periods to span year boundaries.
In MySQL 8, use window functions!
select t.*
from (select t.*,
row_number() over (partition by year(date) order by next_5_days_sales) as seqnum
from (select t.*,
sum(t2.sales) over (order by date range between current row and 4 following) as as next_5_days_sales
from t
) t
) t
where seqnum = 1;
My problem: I have table with price and date. I need to have an average price from last 7 existing days. E.g.: I have prices from today, yesterday, 30 days ago, 43 days ago etc. I need an average not from the last 7 days, but from the last 7 existing days.
My code:
SELECT AVG(price)
FROM table
GROUP BY date
ORDER BY date DESC LIMIT 7
But I have 7 average price from every day.
Maybe someone has another idea
Use a subquery to get the last 7 existing days, get the earliest of those dates, then join that with the table.
SELECT AVG(price)
FROM table AS t1
JOIN (SELECT MIN(dateday) AS mindate
FROM
(SELECT DATE(date) AS dateday
FROM table
GROUP BY dateday
ORDER BY dateday DESC LIMIT 7
) AS x
) AS t2
ON t1.date >= t2.mindate
use avg function and subquery
select avg(price)
from
(SELECT date,price
FROM table
ORDER BY date desc limit 7
) as t
I already count inscriptions, this week.
But i need to count inscription per week last 12 weeks, and send it in an array.
My actual request is :
SELECT COUNT(*) FROM PERSON
YEAR(date_inscription) = YEAR(NOW())
AND WEEK(date_inscription) = WEEK(NOW())
SELECT YEARWEEK(date_inscription) as yweek,
COUNT(*) as cnt
FROM PERSON
where YEARWEEK(date_inscription) >= YEARWEEK(curdate()) - 12
group by yweek
I'm trying to write a query that returns a list of dates and the DISTINCT COUNT of User IDs for the 7 days preceding each date. The table I'm working with is simple, and looks like this:
Started UserId
"2012-09-25 00:01:04" 164382
"2012-09-25 00:01:39" 164382
"2012-09-25 00:02:37" 166121
"2012-09-25 00:03:35" 155682
"2012-09-25 00:04:18" 160947
"2012-09-25 00:08:19" 165806
I can write the query for output of an individual COUNT as follows:
SELECT COUNT(DISTINCT UserId)
FROM Session
WHERE Started BETWEEN '2012-09-18 00:00' AND '2012-09-25 00:00';
But what I'm trying to do is output this COUNT for every day in the table AND the 7 days preceding it. To clarify, the value for September 25th would be the count of DISTINCT User IDs between the 18th and 25th, the 24th the count between 17th and 24th, etc.
I tried the following query but it provides just the COUNT for each day:
SELECT
DATE(A.Started),
Count(DISTINCT A.UserId)
FROM Session AS A
WHERE DATE(A.Started) BETWEEN DATE(DATE_SUB(DATE(DATE(A.Started)),INTERVAL 7 DAY)) AND DATE(DATE(A.Started))
GROUP BY DATE(A.Started)
ORDER BY DATE(A.Started);
And the output looks like this:
DATE(A.Started) "Count(DISTINCT A.UserId)"
2012-09-18 709
2012-09-19 677
2012-09-20 658
2012-09-21 556
2012-09-22 530
2012-09-23 479
2012-09-24 528
2012-09-25 480
...
But as I said, those are just the daily counts. Initially I thought I could just sum the 7 day values, but that will invalidate the DISTINCT clause. I need the DISTINCT UserId counts for each 7 day period preceding a given date.
This query should work for you:
SELECT
DATE_FORMAT(d1.Started, '%Y-%m-%d') AS Started,
COUNT(DISTINCT d2.UserID) Users
FROM
(
SELECT
DATE(Started) AS Started
FROM
Session
GROUP BY
DATE(Started)
) d1
INNER JOIN
(
SELECT DISTINCT
DATE(Started) AS Started,
UserID
FROM
Session
) d2
ON d2.Started BETWEEN d1.Started - INTERVAL 7 DAY AND d1.Started
GROUP BY
d1.Started
ORDER BY
d1.Started DESC
Visit http://sqlfiddle.com/#!2/9339c/5 to see this query in action.
try:
Select Distinct Date(A.Started), Count(B.UserId)
From Session a
Join Session b
On b.Start Between AddDate(A.Start, day, -7) And A.Start
I'm not a MySQL guy, so the syntax might not be correct, but the pattern will work....