MYSQL: Transfer values from one table to another based on date/hour - mysql

i have the following MYSQL tables:
Part of the input table 'input':
and part of the Output Table 'output':
both date/time columns are pre given and cannot be changed. they are the basis of the MYSQL code I want to use to do the following:
I want to sum all values from 'total' column of the input table from the same date and same hour and put them into 'total' column of the output table where the 'time' column has the same date and same hour as in the input table.
Would this be possible with MYSQL only?
Or do I need PHP as well?
The input table has about 400,000 values.
I started with:
SELECT SUM(total) FROM input
WHERE date BETWEEN '2019-06-06 00:00:00' AND '2019-06-06 23:59:59'
But I dont know how to continue.
Any help would be appreciated. Thanks in advance :)

Get the sums in the input table and join to the output table in the UPDATE statement:
update output o
inner join (
select date_format(date, '%Y%m%d%H') hour, sum(total) total
from input
group by date_format(date, '%Y%m%d%H')
) i on i.hour = date_format(o.date, '%Y%m%d%H')
set o.total = i.total

UPDATE outputtable,
(SELECT Sum(total) SUM,
Year(date) year,
Month(date) month,
Day(date) day,
Hour(date) hour
FROM inputtable
GROUP BY Year(date),
Month(date),
Day(date),
Hour(date)) InputT SET total = InputT.sum WHERE Year(outputtable.date) = InputT.year
AND Month(outputtable.date) = InputT.month
AND Day(outputtable.date) = InputT.day
AND Hour(outputtable.date) = InputT.hour;

Related

Avg function not returning proper value

I expect this query to give me the avg value from daily active users up to date and grouped by month (from Oct to December). But the result is 164K aprox when it should be 128K. Why avg is not working? Avg should be SUM of values / number of current month days up to today.
SELECT sq.month_year AS 'month_year', AVG(number)
FROM
(
SELECT CONCAT(MONTHNAME(date), "-", YEAR(DATE)) AS 'month_year', count(distinct id_user) AS number
FROM table1
WHERE date between '2020-10-01' and '2020-12-31 23:59:59'
GROUP BY EXTRACT(year_month FROM date)
) sq
GROUP BY 1
Ok guys thanks for your help. The problem was that on the subquery I was pulling the info by month and not by day. So I should pull the info by day there and group by month in the outer query. This finally worked:
SELECT sq.day_month, AVG(number)
FROM (SELECT date(date) AS day_month,
count(distinct id_user) AS number
FROM table_1
WHERE date >= '2020-10-01' AND
date < '2021-01-01'
GROUP BY 1
) sq
GROUP BY EXTRACT(year_month FROM day_month)
Do not use single quotes for column aliases!
SELECT sq.month_year, AVG(number)
FROM (SELECT CONCAT(MONTHNAME(date), '-', YEAR(DATE)) AS month_year,
count(distinct id_user) AS number
FROM table1
WHERE date >= '2020-10-01' AND
date < '2021-01-01'
GROUP BY month_year
) sq
GROUP BY 1;
Note the fixes to the query:
The GROUP BY uses the same columns as the SELECT. Your query should return an error (although it works in older versions of MySQL).
The date comparisons have been simplified.
No single quotes on column aliases.
Note that the outer query is not needed. I assume it is there just to illustrate the issue you are having.

How to find which year do values tend to increase in ? in SQL

Basically I have a table like this:
Table Time:
ID.......Date
1......08/26/2016
1......08/26/2016
2......05/29/2016
3......06/22/2016
4......08/26/2015
5......05/23/2015
5......05/23/2015
6......08/26/2014
7......04/26/2014
8......08/26/2013
9......03/26/2013
The query should return like this
Year........CountNum
2016........4
2015........3
To find out which year does its value tend to increase in. I notice that I want to display the years that have more values (number of row in this case) than the previous year.
What I've done so far
SELECT Year, count(*) as CountNum
FROM Time
GROUP BY Year
ORDER BY CountNum DESC;
I don't know how to get the year from date format. I tried year(Date) function, but I got Null data.
Please help!
It should works fine.
select year(date), count(*) as countNum
from time
group by year(date)
order by countNum
Join the grouped data to itself with 1 year offset:
select
a.*
from
(
select year(`Date`) as _year, count(*) as _n
from time group by 1
) a
left join
(
select year(`Date`) as _year, count(*) as _n
from time group by 1
) b
on a._year = b._year-1
where a._n > b._n
order by 1

Count on curdate() in mysql

I have a user_entry table which contains a date field. data type is datetime.
data base is mysql.
I want a count of current date and current month and all data of current date.
How can I get this?
I tried below query but it's not working.
select * from table
where DATE(date) = CURDATE()
SELECT date FROM `test` WHERE date = CURDATE()
or
SELECT date FROM `test` WHERE date = DATE('2016-04-04')
it's work.
if you want the number of matches:
SELECT COUNT(date) from test WHERE date = CURDATE()
What is the data type of field 'date'?
To obtain the DAY/MONTH you can use the corresponding functions
SELECT MONTH(date), DAY(date) from test
Moreover, you can use groups to create a complete report
SELECT COUNT(date), date from test GROUP BY DAY(date), MONTH(date)
i used below query and it works for me.
SELECT *
FROM `user_entry`
WHERE DATE( DATE ) = DATE( NOW( ) )

mysql GROUP BY with multiple columns

I have table where date is stored as 3 columns in the table, i.e as below
`periodYear`
`periodMonth`
`billDay`
Which is causing me problems, when i want to generate reports based on the DATE which is a combination of above three. for example
SELECT SUM(amount) as Total,
FROM invoice
WHERE `periodYear` = 2014,
GROUP BY `billDay`,`periodMonth`,`periodYear`
Can somebody help me to explain how to solve this problem ?
For example I want to list all the totals last year on daily base,
If it's a date column, I could have just group by date, but in this case I don't know how to do that, because if you group by billday,..,., then it going group based on the day not DATE.. you see what I mean ?
Try this,
SELECT SUM(amount) as Total FROM invoice WHERE `periodYear`=2014 GROUP BY CONCAT(periodYear, '-', periodMonth, '-', billDay);
You could just concatenate the values together and then group on that:
SELECT SUM(amount) as Total FROM invoice
WHERE periodYear=2014
GROUP BY CONCAT(billDay, '-', periodMonth, '-', periodYear)
Or if you would want to convert to and actual date format for easier sorting afterwards:
SELECT SUM(amount) as Total FROM invoice
WHERE periodYear=2014
GROUP BY CONCAT(periodYear,
'-',
LPAD(periodMonth, 2, '00'),
'-',
LPAD(billDay, 2, '00')
)
I think what you want is just the opposite of what you've tried.
SELECT SUM(amount) as 'Total'
FROM `invoice`
WHERE `periodYear` = 2014
GROUP BY `periodYear`, `periodMonth`, `billDay`
This will group first by year, then by month, then by day. Biggest to smallest.

MySQL Query not selecting correct date range

Im currently trying to run a SQL query to export data between a certain date, but it runs the query fine, just not the date selection and i can't figure out what's wrong.
SELECT
title AS Order_No,
FROM_UNIXTIME(entry_date, '%d-%m-%Y') AS Date,
status AS Status,
field_id_59 AS Transaction_ID,
field_id_32 AS Customer_Name,
field_id_26 AS Sub_Total,
field_id_28 AS VAT,
field_id_31 AS Discount,
field_id_27 AS Shipping_Cost,
(field_id_26+field_id_28+field_id_27-field_id_31) AS Total
FROM
exp_channel_data AS d NATURAL JOIN
exp_channel_titles AS t
WHERE
t.channel_id = 5 AND FROM_UNIXTIME(entry_date, '%d-%m-%Y') BETWEEN '01-05-2012' AND '31-05-2012' AND status = 'Shipped'
ORDER BY
entry_date DESC
As explained in the manual, date literals should be in YYYY-MM-DD format. Also, bearing in mind the point made by #ypercube in his answer, you want:
WHERE t.channel_id = 5
AND entry_date >= UNIX_TIMESTAMP('2012-05-01')
AND entry_date < UNIX_TIMESTAMP('2012-06-01')
AND status = 'Shipped'
Besides the date format there is another issue. To effectively use any index on entry_date, you should not apply functions to that column when you use it conditions in WHERE, GROUP BY or HAVING clauses (you can use the formatting in SELECT list, if you need a different than the default format to be shown). An effective way to write that part of the query would be:
( entry_date >= '2012-05-01'
AND entry_date < '2012-06-01'
)
It works with DATE, DATETIME and TIMESTAMP columns.