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
Related
I'm trying to get last 12 months data in Mysql using below query but i'm getting all the data not last 12 months data i gone through few of the post but helpful
My CreatedDate format is like '2020-04-17 12:03:59'
SELECT date_format(createdDate,'%m') as Month,
count(*) as count,
date_format(createdDate,'%Y') as Year
FROM tablename
WHERE DATE_ADD(Now(),INTERVAL- 12 MONTH)
GROUP BY Year,
Month
ORDER by Year desc,
Month desc;
and also need help you Insert 0 if no data found in that month.
You may use a calendar table here:
SELECT
cal.dt,
COUNT(t.createdDate) AS count
FROM
(
SELECT DATE_FORMAT(CURDATE(), '%Y-%m') AS dt UNION ALL
SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 1 MONTH), '%Y-%m') UNION ALL
SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 2 MONTH), '%Y-%m') UNION ALL
SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 3 MONTH), '%Y-%m') UNION ALL
SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 4 MONTH), '%Y-%m') UNION ALL
SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 5 MONTH), '%Y-%m') UNION ALL
SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 6 MONTH), '%Y-%m') UNION ALL
SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 7 MONTH), '%Y-%m') UNION ALL
SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 8 MONTH), '%Y-%m') UNION ALL
SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 9 MONTH), '%Y-%m') UNION ALL
SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 10 MONTH), '%Y-%m') UNION ALL
SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 11 MONTH), '%Y-%m')
) cal
LEFT JOIN tablename t
ON cal.dt = DATE_FORMAT(createdDate, '%Y-%m')
WHERE
t.createdDate >= DATE_SUB(CURDATE(), INTERVAL 12 MONTH)
GROUP BY
cal.dt
ORDER BY
cal.dt DESC;
In MySQL 8+, you can use a recursive CTE to generate the dates:
with recursive dates as (
select curdate() - interval (1 - day(curdate())) day as yyyymm, 1 as lev
union all
select yyyymm - interval 1 month, lev + 1
from dates
where lev < 12
)
select d.yyyymm, count(t.createdDate) as cnt
from dates d left join
tablename t
on t.createdDate >= d.yyyymm and
t.createdDate < d.yyyymm + interval 1 month
group by d.yyyymm;
Note that this doesn't split the year and month into separate columns, but you can do that if you really want.
Also, this provide the current month with partial data. You can adjust the logic if you only want complete months.
I'm using MySQL with PHP. Here is my query on which I'm getting the error.
$query =
"SELECT days.day, count(myDataTable.appId) as countf, count(myDataTable.appId) as counts
FROM
(
select curdate() as day
union select curdate() - interval 1 day
union select curdate() - interval 2 day
union select curdate() - interval 3 day
union select curdate() - interval 4 day
union select curdate() - interval 5 day
union select curdate() - interval 6 day
union select curdate() - interval 7 day
union select curdate() - interval 8 day
union select curdate() - interval 9 day
) days
left join myDataTable as n1
on days.day = n1.date AND n1.appId = '$id' AND n1.status = 'ERROR'
group by days.day
left join myDataTable as n2
on days.day = n2.date AND n2.appId = '$id' AND n2.status = 'SUCCESS'
group by days.day";
The error log is:
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'left join myDataTable on days.day = myDataTable.date AND myDataTable.appId ' at line 17
It helps to properly indent your SQL so you can spot the mistakes. Indenting by the main keywords (SELECT, FROM, WHERE, HAVING, GROUP BY, and ORDER BY) will help you spot them quickly:
SELECT
days.day,
count (myDataTable.appId) as countf,
count(myDataTable.appId) as counts
FROM
(
select curdate() as day
union select curdate() - interval 1 day
union select curdate() - interval 2 day
union select curdate() - interval 3 day
union select curdate() - interval 4 day
union select curdate() - interval 5 day
union select curdate() - interval 6 day
union select curdate() - interval 7 day
union select curdate() - interval 8 day
union select curdate() - interval 9 day
) days
left join myDataTable as n1
on days.day = n1.date AND n1.appId = '$id' AND n1.status = 'ERROR'
group by
days.day
left join myDataTable as n2
on days.day = n2.date AND n2.appId = '$id' AND n2.status = 'SUCCESS'
group by
days.day
You can see that you have two GROUP BY's which won't work. Furthermore you have a LEFT JOIN hanging out in the first GROUP BY clause, which doesn't work either. Removing that first GROUP BY will get you closer:
SELECT
days.day,
count (myDataTable.appId) as countf,
count(myDataTable.appId) as counts
FROM
(
select curdate() as day
union select curdate() - interval 1 day
union select curdate() - interval 2 day
union select curdate() - interval 3 day
union select curdate() - interval 4 day
union select curdate() - interval 5 day
union select curdate() - interval 6 day
union select curdate() - interval 7 day
union select curdate() - interval 8 day
union select curdate() - interval 9 day
) days
left join myDataTable as n1
on days.day = n1.date AND n1.appId = '$id' AND n1.status = 'ERROR'
left join myDataTable as n2
on days.day = n2.date AND n2.appId = '$id' AND n2.status = 'SUCCESS'
group by
days.day
No you have a proper FROM clause. This is the first part that your Database looks at so it knows from where it is getting it's data and how it joins together. Your table aliases are set here and then used EVERYWHERE else in the query. Which leads you to the second problem.
You reference myDataTable up in your SELECT clause, but by the time the database is looking at your SELECT myDataTable isn't in context. The aliases n1 and n2 are though, so change these to reference your table aliases:
SELECT
days.day,
count (n1.appId) as countf,
count(n2.appId) as counts
FROM
(
select curdate() as day
union select curdate() - interval 1 day
union select curdate() - interval 2 day
union select curdate() - interval 3 day
union select curdate() - interval 4 day
union select curdate() - interval 5 day
union select curdate() - interval 6 day
union select curdate() - interval 7 day
union select curdate() - interval 8 day
union select curdate() - interval 9 day
) days
left join myDataTable as n1
on days.day = n1.date AND n1.appId = '$id' AND n1.status = 'ERROR'
left join myDataTable as n2
on days.day = n2.date AND n2.appId = '$id' AND n2.status = 'SUCCESS'
group by
days.day
Lastly, instead of joining your myDataTable in twice for each status, you can use a CASE statement in your SELECT:
SELECT
days.day,
SUM(CASE WHEN n1.status = 'ERROR' THEN 1 ELSE 0 END) as countf,
SUM(CASE WHEN n1.status = 'SUCCESS' THEN 1 ELSE 0 END) as counts
FROM
(
select curdate() as day
union select curdate() - interval 1 day
union select curdate() - interval 2 day
union select curdate() - interval 3 day
union select curdate() - interval 4 day
union select curdate() - interval 5 day
union select curdate() - interval 6 day
union select curdate() - interval 7 day
union select curdate() - interval 8 day
union select curdate() - interval 9 day
) days
left join myDataTable as n1
on days.day = n1.date AND n1.appId = '$id'
group by
days.day
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 want to count amount of ID's for each month for the last half year, here is my query:
SELECT count(`Id`) FROM `items` WHERE MONTH(Created) = MONTH(CURRENT_DATE) UNION SELECT `count(`Id`) FROM `items` WHERE MONTH(Created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH) UNION SELECT count(`Id`) FROM `items` WHERE MONTH(Created) = MONTH(CURRENT_DATE - INTERVAL 2 MONTH) UNION SELECT count(`Id`) FROM `items` WHERE MONTH(Created) = MONTH(CURRENT_DATE - INTERVAL 3 MONTH) UNION SELECT count(`Id`) FROM `items` WHERE MONTH(Created) = MONTH(CURRENT_DATE - INTERVAL 4 MONTH) UNION SELECT count(`Id`) FROM `items` WHERE MONTH(Created) = MONTH(CURRENT_DATE - INTERVAL 5 MONTH);`
Created is the time stamp of the created row.
My problem is getting the fourth, fifth and sixth months. Because they were created in 2013 (different year), my query can't get their result.
I would start with something like this:
SELECT MONTH(created), count(*)
FROM `items`
WHERE Created >= LAST_DAY(current_date() - INTERVAL 6 MONTH) + INTERVAL 1 DAY
GROUP BY MONTH(created)
Where LAST_DAY(current_date() - INTERVAL 6 MONTH) + INTERVAL 1 DAY will return the first day of the month where to start the count, you might also want to group by month and year:
SELECT DATE_FORMAT(created, '%Y-%m'), count(*)
FROM `items`
WHERE Created >= LAST_DAY(current_date() - INTERVAL 6 MONTH) + INTERVAL 1 DAY
GROUP BY DATE_FORMAT(created, '%Y-%m')
I am trying to get the amount of users signed up in the past 7 days to display on a chart and it would be nice if mysql returned 0 instead of no row. Currently it just returns a row for each day THAT has a value
SELECT date(created_at),
count(id)
FROM user_accts
WHERE date(created_at) < NOW()
AND date(created_at) > DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY date(created_at);
Try:
SELECT DATE_SUB(CURDATE(), INTERVAL i DAY) date_created_at,
count(id)
FROM (SELECT 1 i UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5 UNION ALL
SELECT 6 UNION ALL
SELECT 7) i
LEFT JOIN user_accts ON date(created_at) = DATE_SUB(CURDATE(), INTERVAL i DAY)
/*AND owner_id = '131'*/
GROUP BY DATE_SUB(CURDATE(), INTERVAL i DAY)