between date inteval mysql not showing today - mysql

my query:
SELECT p.idprd,
p.nmprd,
pe.idprd,
pe.stockjual,
pe.stockkeluar,
pe.tothrgjual,
pe.tgljual
FROM tbproduk AS p
INNER JOIN (
SELECT idprd,
Sum(stockjual) AS 'stockjual',
Sum(stockkeluar) AS 'stockkeluar',
Sum(tothrgajual) AS 'tothrgjual',
tgljual
FROM tbpenjualan
WHERE '2019-01-06' >= '2019-01-06' - INTERVAL 7 day
AND '2019-01-06' < '2019-01-06' + INTERVAL 7 day
GROUP BY idprd
) AS pe ON p.idprd = pe.idprd
my result
my data:
date '2019-01-06' not showing. how to my currentdate to showing

GROUP BY has missing column - which would prevent you to even execute SQL statement successfully. But after adjusting SQL statement, results include correct sets of data.
SELECT p.idprd,
p.nmprd,
pe.idprd,
pe.stockjual,
pe.stockkeluar,
pe.tothrgjual,
pe.tgljual
FROM tbproduk AS p
INNER JOIN (
SELECT idprd,
Sum(stockjual) AS 'stockjual',
Sum(stockkeluar) AS 'stockkeluar',
Sum(tothrgajual) AS 'tothrgjual',
tgljual
FROM tbpenjualan
WHERE '2019-01-06' >= '2019-01-06' - INTERVAL 7 day
AND '2019-01-06' < '2019-01-06' + INTERVAL 7 day
GROUP BY idprd, tgljual
) AS pe ON p.idprd = pe.idprd
ORDER BY pe.tgljual desc;
Query Result:

Related

Error when I execute a recursive query in MySQL

I have the following query:
with recursive dates as (
select curdate() as dte, 1 as lev
union all
select dte - interval 1 day, lev + 1
from dates
where lev < 7
)
select DATE_FORMAT(d.dte, '%d') AS date, count(distinct c.id) AS cards, count(distinct mc.id) AS people_cards
from dates d
left join
cards c
on c.publicated = 1 and
c.publication_date >= d.dte and
c.publication_date < d.dte + interval 1 DAY
left join
people_cards mc
on mc.publicated = 1 and
mc.publication_date >= d.dte and
mc.publication_date < d.dte + interval 1 day
group by d.dte
This query works in my localhost, but when I deploy my project in heroku, this query doesn't work. When I execute it in my SQL Client, I get the following result:
But in my localhost, I get this result:
In my local, I'm using MariaDB 10.5.
How can I solve this problem?

Select the next day occurance from the table

This is my db structure of the table game days. Every game ends at 8:00 pm . Here all the game id is same.So now i want to query by the game id like this way that if today is monday and it is before 8:00 pm so it will fetch only the game_days with value of day='Monday'.Once 8:00pm is over then it will show the row with the value of day='Wednesday' until wednesday 8:00pm and after 8:00 pm it will show the row with the value of day='Friday' until Friday 8:00pm and then again after Friday 8:00pm it will show Monday...
So what will be the query for this ?
I think you just want the date offset by 4 hours. One method is:
where date(updated_at + interval 4 hour) = curdate()
I am guessing that updated_at is the column you want to reference, but it can be any date/time column.
I prefer to express this as:
where updated_at >= curdate() - interval 4 hour and
updated_at < curdate() + interval 1 day - interval 4 hour
This version can make use of an index on the date/time column.
Please try this (updated based on comments, replace table_name with appropriate table name is your db):
SELECT *
FROM `table_name`
WHERE day = (
SELECT t3.day FROM `table_name` as t3
LEFT JOIN (
SELECT HOUR(NOW()),
CASE
WHEN HOUR(NOW()) <= 19 THEN DAYNAME(NOW() + INTERVAL t.p DAY)
ELSE DAYNAME(NOW() + INTERVAL (t.p + 1) DAY)
END AS day,
CASE
WHEN HOUR(NOW()) <= 19 THEN t.p
ELSE t.p + 1
END as p
FROM (
SELECT 0 as p
UNION SELECT 1 as p
UNION SELECT 2 as p
UNION SELECT 3 as p
UNION SELECT 4 as p
UNION SELECT 5 as p
UNION SELECT 6 as p
) t
) t2 on t3.day = t2.day
ORDER BY t2.p ASC LIMIT 1
)

Unable to JOIN the same table twice based on two conditions

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

Combine two select statements grouped by date returning two columns of data

This seems like an easy task but my basic sql knowledge is failing me as I'm still learning.
Basically, I'm trying to combine:
SELECT DATE(created) DATE, COUNT(DISTINCT created) newpost FROM surveys
WHERE created >= Last_day(CURRENT_DATE) + INTERVAL 1 DAY - INTERVAL 1 MONTH
AND created < last_day(CURRENT_DATE) + INTERVAL 1 DAY GROUP BY DATE(created);
and
SELECT DATE(TIMESTAMP) DATE,subs FROM trafficstats
WHERE TIMESTAMP >= LAST_DAY(CURRENT_DATE) + INTERVAL 1 DAY - INTERVAL 1 MONTH
AND TIMESTAMP < LAST_DAY(CURRENT_DATE) + INTERVAL 1 DAY;
into one query that will return data, grouped by date, into two additional columns - newposts and subs.
I've tried using UNION, which doesn't seem to be giving me the output I want. It combined the data into one column (newpost), and also didn't group by date.
I'm still fairly new to writing MySQL queries, and I've tried searching for answers to no avail. Hoping to seek the knowledge of those smarter than me here.
You could use JOIN
select t1.DATE, t1.newpost, t2.subs
from (
SELECT DATE(created) DATE, COUNT(DISTINCT created) newpost
FROM surveys
WHERE created >= Last_day(CURRENT_DATE) + INTERVAL 1 DAY - INTERVAL 1 MONTH
AND created < last_day(CURRENT_DATE) + INTERVAL 1 DAY
GROUP BY DATE(created)
) t1
left join (
SELECT DATE(TIMESTAMP) DATE, subs
FROM trafficstats
WHERE TIMESTAMP >= LAST_DAY(CURRENT_DATE) + INTERVAL 1 DAY - INTERVAL 1 MONTH
AND TIMESTAMP < LAST_DAY(CURRENT_DATE) + INTERVAL 1 DAY
) t2 on t1.DATE = t2.DATE
I guess you want one row per distinct date, with two different count values shown.
This kind of query is slightly tricker than it seems at first glance, because the two summary queries might have different sets of dates.
So you need to start with a subquery that yields all possible dates of interest. You then need to LEFT JOIN each summary query to it. You must use LEFT JOIN instead of the ordinary inner JOIN, because LEFT JOIN doesn't suppress rows from the right side of the join when they don't match any rows from the left side.
Here goes:
All your dates. Notice the UNION operation is a setwise (duplicate-removing) union operation.
SELECT DISTINCT DATE(created) DATE FROM newpost
WHERE created >= Last_day(CURRENT_DATE) + INTERVAL 1 DAY - INTERVAL 1 MONTH
AND created < last_day(CURRENT_DATE) + INTERVAL 1 DAY
UNION
SELECT DISTINCT DATE(TIMESTAMP) DATE FROM trafficstats
WHERE TIMESTAMP >= LAST_DAY(CURRENT_DATE) + INTERVAL 1 DAY - INTERVAL 1 MONTH
AND TIMESTAMP < LAST_DAY(CURRENT_DATE) + INTERVAL 1 DAY
Then you need your two summary subqueries. The first one is this. Notice that I changed COUNT(DISTINCT created) to COUNT(*) because I don't understand the logic behind the DISTINCT there. Can you have more than one row for a single post; do you tell them apart by timestamp? If you have a row for each post you should COUNT(*).
SELECT DATE(created), COUNT(*) newposts
FROM newpost
GROUP BY DATE(created)
The second summary is this. Again, I counted rows.
SELECT DATE(TIMESTAMP), COUNT(*) subs
FROM trafficstats
GROUP BY DATE(TIMESTAMP)
Finally, join those three subqueries like so. You get the dates from the first subquery, and the summary-by-date information from the second two subqueries.
SELECT dates.DATE, posts.newposts, subs.subs
FROM ( /* date subquery */ ) dates
LEFT JOIN ( /* posts subquery */ ) posts ON dates.DATE = posts.DATE
LEFT JOIN ( /* subs subquery */ ) subs ON dates.DATE = subs.DATE
ORDER BY dates.DATE
Putting it all together:
SELECT dates.DATE, posts.newposts, subs.subs
FROM (
SELECT DISTINCT DATE(created) DATE FROM newpost
WHERE created >= Last_day(CURRENT_DATE) + INTERVAL 1 DAY - INTERVAL 1 MONTH
AND created < last_day(CURRENT_DATE) + INTERVAL 1 DAY
UNION
SELECT DATE(TIMESTAMP) DATE FROM trafficstats
WHERE TIMESTAMP >= LAST_DAY(CURRENT_DATE) + INTERVAL 1 DAY - INTERVAL 1 MONTH
AND TIMESTAMP < LAST_DAY(CURRENT_DATE) + INTERVAL 1 DAY
) dates
LEFT JOIN (
SELECT DATE(created), COUNT(*) newposts
FROM newpost
GROUP BY DATE(created)
) posts ON dates.DATE = posts.DATE
LEFT JOIN (
SELECT DATE(TIMESTAMP), COUNT(*) subs
FROM trafficstats
GROUP BY DATE(TIMESTAMP)
) subs ON dates.DATE = subs.DATE
ORDER BY dates.DATE

mysql arithmetik operation (subtraction) last - first of the day(week, month)

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.