I am trying to select the sum of an integer field for the past 5 days, and I need to group it for each day.
I'm having a bit of issues figuring out the grouping. Here's my sql query so far:
select
sum(`amount_sale`) as total
from `sales`
where the_date >= unix_timestamp((CURDATE() - INTERVAL 5 DAY))
that works fine for generating the sum for all 5 days together, but I need to break this down so that it shows the sum for each of the past 5 days i.e:
day 1 - $200
day 2- $500
day 3 - $20
etc.
SELECT DATE(FROM_UNIXTIME(the_date)) AS dt, SUM(amount_sale) AS total
FROM sales
WHERE the_date >= UNIX_TIMESTAMP((CURDATE() - INTERVAL 5 DAY))
GROUP BY
dt
To returns 0 for missing dates:
SELECT dt, COALESCE(SUM(amount_sale), 0) AS total
FROM (
SELECT CURDATE() - INTERVAL 1 DAY AS dt
UNION ALL
SELECT CURDATE() - INTERVAL 2 DAY AS dt
UNION ALL
SELECT CURDATE() - INTERVAL 3 DAY AS dt
UNION ALL
SELECT CURDATE() - INTERVAL 4 DAY AS dt
UNION ALL
SELECT CURDATE() - INTERVAL 5 DAY AS dt
) d
LEFT JOIN
sales
ON the_date >= UNIX_TIMESTAMP(dt)
AND the_date < UNIX_TIMESTAMP(dt + INTERVAL 1 DAY)
GROUP BY
dt
This is not a very elegant solution, however, MySQL lacks a way to generate recordsets from scratch.
use the format function to return weekday nr: SELECT DATE_FORMAT(the_date, '%w');
use between
like select * from XXX where date between date(...) and date(...) group by date Limit 0,5
should do it
Related
I have the following table called vacations, where the employee id is displayed along with the start and end date of their vacations:
employee
start
end
1001
26/10/21
22/11/21
What I am looking for is to visualize the number of vacation days that each employee had, but separating them by month and without non-working days (Saturdays and Sundays).
For example, if you wanted to view the vacations for employee 1001, the following result should be displayed:
days
month
4
10
16
11
I have the following query that I have worked with:
SELECT id_employee,
EXTRACT(YEAR_MONTH FROM t.Date) as YearMonth,
COUNT(1) as Days
FROM (SELECT v.id_employee,
DATE_ADD(v.start, interval s.seq - 1 DAY) AS Date
FROM vacations v
CROSS JOIN seq_1_to_100 s
WHERE DATE_ADD(v.start, interval s.seq - 1 DAY) <= v.end
ORDER BY v.id_employee, , v.start, s.seq
) t
GROUP BY id_employee,
EXTRACT(YEAR_MONTH FROM t.Date)
With this query I separate the days between a range of two dates with their respective month, but how could I adapt it to stop considering Saturdays and Sundays? I'm working with MySQL 5.7 in phpMyAdmin
instead of count sum the compaarison of weekday function, which give what day it is .
But you should always save fates n a valid mysql manner 2021-10-28
SELECT id_employee,
EXTRACT(YEAR_MONTH FROM t.Date) as YearMonth,
SUM(WEEKDAY(`Date`) < 5) as Days
FROM (SELECT v.id_employee,
DATE_ADD(v.start, interval s.seq - 1 DAY) AS Date
FROM vacations v
CROSS JOIN seq_1_to_100 s
WHERE DATE_ADD(v.start, interval s.seq - 1 DAY) <= v.end
ORDER BY v.id_employee, v.start, s.seq
) t
GROUP BY id_employee,
EXTRACT(YEAR_MONTH FROM t.Date)
I'm trying to get values from dataTable for the last 7 days, if there is no data for specific date zero should be filled in the output:
SELECT calendar.dt, COALESCE(SUM(weight*price),0) AS amount
FROM
(SELECT CURRENT_DATE AS dt
UNION ALL SELECT CURRENT_DATE - INTERVAL 1 DAY
UNION ALL SELECT CURRENT_DATE - INTERVAL 2 DAY
UNION ALL SELECT CURRENT_DATE - INTERVAL 3 DAY
UNION ALL SELECT CURRENT_DATE - INTERVAL 4 DAY
UNION ALL SELECT CURRENT_DATE - INTERVAL 5 DAY
UNION ALL SELECT CURRENT_DATE - INTERVAL 6 DAY) calendar
LEFT JOIN dataTable ON calendar.dt = DATE(dataTable.sold_at);
Request above returns only one record:
Please advise what is wrong with SQL request?
Seems that group by Is missing.
SELECT calendar.dt, COALESCE(SUM(weight*price),0) AS amount
FROM
(SELECT CURRENT_DATE AS dt
UNION ALL SELECT CURRENT_DATE - INTERVAL 1 DAY
UNION ALL SELECT CURRENT_DATE - INTERVAL 2 DAY
UNION ALL SELECT CURRENT_DATE - INTERVAL 3 DAY
UNION ALL SELECT CURRENT_DATE - INTERVAL 4 DAY
UNION ALL SELECT CURRENT_DATE - INTERVAL 5 DAY
UNION ALL SELECT CURRENT_DATE - INTERVAL 6 DAY) calendar
LEFT JOIN dataTable ON calendar.dt = DATE(dataTable.sold_at)
Group by calendar.dt
;
SQL fiddle link: http://sqlfiddle.com/#!9/f151a8e/4
I want to get the three working days from the current date as excluding Saturday and Sunday. can any one help me out here.
I have tried the interval method and DayOfWeek(day) <> 1 AND DayOfWeek(day) <> 7 but it is not giving me the proper result
Not very elegant but
select d
from
(
select curdate() as d
union all
select curdate() + interval 1 day
union all
select curdate() + interval 2 day
union all
select curdate() + interval 3 day
union all
select curdate() + interval 4 day
) tmp
where dayofweek(d) not in (1,7)
order by d
limit 3
i got a MySQL tbl, with some colums, where every 5 min. a new row is inserted with 3 values
1. Auto inc. curent Date Unix timestamp --> date
2. power consumption absolut --> wert01
3. Power Generation absolut --> wert02
To Show this Information in a Graph, for Exampl for weekly power consumption, i need to select the First and the last, which allready Works, but then have to Substract the last from the First and Show only tue result & the day of the werk.
SELECT
(SELECT wert01
FROM sml_splitt
WHERE date >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY
AND date < curdate() - INTERVAL DAYOFWEEK(curdate()) DAY
ORDER BY date DESC LIMIT 1) AS 'last',
(SELECT wert01
FROM sml_splitt
WHERE date >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY
AND date < curdate() - INTERVAL DAYOFWEEK(curdate()) DAY
ORDER BY date LIMIT 1) AS 'lirst
I am searching for some days to find a solution, but with no success.
Hopfuly, you could help me.
If you're happy with your query, then you can do the math by nesting it one more time like this: http://sqlfiddle.com/#!9/515ef/1
select t1.last, t1.first, t1.last - t1.first as result
from (
select (
select wert01
from sml_splitt
where dt >= curdate() - interval dayofweek(curdate()) + 6 day
and dt < curdate() - interval dayofweek(curdate()) day
order by dt desc limit 1
) as 'last',
(
select wert01
from sml_splitt
where dt >= curdate() - interval dayofweek(curdate()) + 6 day
and dt < curdate() - interval dayofweek(curdate()) day
order by dt limit 1
) as 'first'
) t1
;
If you really want to work with this data by week for reporting purposes, let me suggest a couple of views. The first will give you all of your distinct beginning of week dates:
create view v1 as
select date(dt) as week_begins
from sml_splitt
where dayofweek(dt) = 1
group by week_begins
The second view joins the first view with itself to give you a week beginning and week ending range:
create view v2 as
select t1.week_begins, coalesce(t2.week_begins,now()) as week_ends
from v1 t1
left join v1 t2
on t2.week_begins = t1.week_begins + interval 7 day
You can see the results here: http://sqlfiddle.com/#!9/a4d1b3/2. Notice that I'm using now() to get the current date and time if the week hasn't ended yet.
From there you can join your view with your original table and use min() and max() function with grouping to get the starting and ending 'wert' values and do any calculations on them that you like.
Here's an example: http://sqlfiddle.com/#!9/a4d1b3/6
select week_begins, week_ends,
min(wert01) as start_wert01,
max(wert01) as end_wert01,
max(wert01) - min(wert01) as power_consumed,
min(wert02) as start_wert02,
max(wert02) as end_wert02,
max(wert02) - min(wert02) as power_generated,
(max(wert02) - min(wert02)) - (max(wert01) - min(wert01)) as net_generated
from v2
inner join sml_splitt
on sml_splitt.dt >= v2.week_begins
and sml_splitt.dt < v2.week_ends
group by week_begins
I hope that helps.
The purpose of this query:
contracts in the database have a start date, contract date and closing date.
When a contract goes pending, the contract date is set and the closing date is set to a around 40 days in the future. I need to run a query that gets the contracts that have a contract date in the past and closing date that has not been reached to find the number of pending contracts for that month. This query generate a report of pending contracts from the last full month and going back 12 months.
My thought is to get the last day of each month and count the number of contracts that have closing date > the last day of month and contract date <= last day of month
The following query executes in 51ms. the query returns rows for July
SELECT DATE_FORMAT(LAST_DAY(NOW() - INTERVAL 2 MONTH), '%Y-%m-%d 23:59:59') as lastDay,
count(*) as total FROM contracts
WHERE L_ClosingDate >= DATE_FORMAT(LAST_DAY(NOW() - INTERVAL 2 MONTH), '%Y-%m-%d 23:59:59')
AND L_ContractDate <= DATE_FORMAT(LAST_DAY(NOW() - INTERVAL 2 MONTH), '%Y-%m-%d 23:59:59')
Now I need to run the query to get rows grouped by month, so I altered the query to the following:
select MONTH(L_ClosingDate) as m, YEAR(L_ClosingDate) as y,
(SELECT count(*) FROM contracts WHERE L_ClosingDate >= DATE_FORMAT(LAST_DAY(CONCAT(y,'-',m,'-',LPAD(1,2,'00'))), '%Y-%m-%d 23:59:59')
AND L_ContractDate <= DATE_FORMAT(LAST_DAY(CONCAT(y,'-',m,'-',LPAD(1,2,'00'))), '%Y-%m-%d 23:59:59')
) as total
FROM contracts
WHERE L_ClosingDate > DATE_ADD(NOW(), INTERVAL -2 MONTH)
AND L_CLosingDate < DATE_ADD(NOW(), INTERVAL -1 MONTH)
GROUP BY YEAR(L_ClosingDate), MONTH(L_ClosingDate)
ORDER BY L_ClosingDate DESC
It executes forever...
I've tweaked it and found that the MONTH and YEAR 'm' and 'y' in the subquery is causing the problem. If I hardcode a date it executes as expected.
Expected output:
Month | Year | total
8 | 2015 | 74
7 | 2015 | 87
6 | 2015 | 45
I'm working on getting some sample data
Is there another way to perform the group by query?
How about this? (Assumes closing date is a datetime)
SELECT MONTH(L_ClosingDate) as m, YEAR(L_ClosingDate) as y
, count(*) as total
FROM contracts
WHERE L_ClosingDate >= LAST_DAY(CURDATE() - INTERVAL 3 MONTH) + 1 DAY
AND L_CLosingDate < LAST_DAY(CURDATE() - INTERVAL 1 MONTH) + INTERVAL 1 DAY
GROUP BY m, y
ORDER BY y DESC, m DESC
;
The easy way of solve this is create a months table, and that is easy to do because only take 1200 rows for whole century.
CREATE TABLE months (
month_id int,
beginDay date,
lastDay date
)
Then your query become much more simple. Just join and calculate between