I have a date/time field in my table called startTime.
I would like the output as follows:
select
YEAR(startTime),
MONTH(startTime),
DAY(startTime),
dayofmonth(startTime),
startTime,
...
This is fine, and I only have to group by startTime.
However, for my output, I am only really interested in the date part of the startTime.
So I changed my output to be
select
YEAR(startTime),
MONTH(startTime),
DAY(startTime),
dayofmonth(startTime),
DATE(startTime),
...
When I try to run this, SQL makes me group by Year, Month, day, dayofmonth and date(startTime).
This seems to be a quirk of the date() function?
I thought maybe it's due to the time part of the startTime field, but Year, Month, Day and dayofmonth are no more granular than a date so I am confused as why I have to group by those.
Any insights greatly appreciated!
My code currently:
YEAR(startTime),
MONTH(startTime),
DAY(startTime),
dayofmonth(startTime),
date(startTime),
count(id)
from
bookings
group by 1, 2, 3, 4, 5
in your select statement we must have distinct values of selected column (as a group) for every distinct value given value of what we group them by.
For example if you have startime in your select clause, and also in group by clause, we get distinct values of selected attributes - date, month, year, & startTime for every unique value of starttime. But if you remove starttime from select clause, the attributes selected are no longer guaranteed to be unique.
Consider 2 startTime values 2020-03-12T01:01:01.000UTC and 2020-03-12T02:02:02.000UTC its expected to produce two rows if we group by startTime (as two distinct startTimes), but the selected values for year, month and date would be same in both of these rows (as they differ only in time part) which is breaking the group by contract.
Hence we can only have group of attributes in select clause which MUST provide a different value for every combination of attributes in the group by clause.
Related
I am trying to fetch the count of records entered in each month of the financial year
For example, I have declared a column called issue in varchar because the data what I am taking is issues of the particular machine. And for example, let's say one issue is raised in July month I enter the data as 'Jul 19-1' and the again issue is raised in the month of September again I go back to the issue happened in July and enter the data as 'sep19-2'.
So in the backend, it takes as jul19-1 sep19-2
What can be the query that I can write for counting the number of issues raised in each month
I tried the below query but
SELECT COUNT(month_nc)
FROM `ncr`
WHERE month_nc='Jul18-1'
In some months there will be only one issue so I can the count of the month given in the above query
What will be the query if I want to fetch the count of each month
id issue issue_month
1 bearing jul18-1
sep18-2
2 motor jul18-2
3 battery apr18-3
ps: issue_month is declared in varchar(10)
Here are two methods. One using strings:
select left(issue_month, 5), count(*)
from t
group by left(issue_month, 5), count(*)
This will not order the values correctly.
You can convert to a date to order properly:
order by str_to_date(concat('01', left(issue_month, 5)), '%d%b%y')
Or, represent the dates correctly:
select str_to_date(concat('01', left(issue_month, 5)), '%d%b%y') as yyyymm, count(*)
from t
group by yyyymm
order by yyyymm;
Here is what you can do to split your issue_month into "month_year" and "issue_count"
yourTable
select id,
issue,
issue_month,
REGEXP_SUBSTR(issue_month, '[^-]+', 1) as month_year,
REGEXP_SUBSTR(issue_month, '[^-]+', 1,2 ) as issue_count
from yourTable;
Now you can aggregate the issue_count across issues or year_months or any other field in your table.
For example, to get the sum of all the issues for any given month_year
select
month_year,
sum(issue_count) issue_count
from
(select
id, issue, issue_month,
REGEXP_SUBSTR(issue_month, '[^-]+', 1) as month_year,
REGEXP_SUBSTR(issue_month, '[^-]+', 1,2 ) as issue_count
from yourTable) foo
group by month_year;
I have a table - accounts, and it has 3 columns: id , timestamp and value.
I need to create a query that returns a table which in each row it will be the month (2, 3, etc.) and the sum of the values from this month.
for example: if my table will have 3 rows from January and one row from February, the query will return a two-rows table within the first row it'll be 1 and the sum of January's values, and the second will be 2 and the sum of February's values.
I have no idea how to begin. can anyone help me?
all you need to do is sum the value and also use mysql's MONTH() function to pull out the month from your timestamp
SELECT SUM(value) as total_amount, MONTH(timestamp) as month_num
FROM table
GROUP BY month_num
GROUP BY is used when you have an aggregate function (in our case its SUM) to know how to group your common fields. without a group by you will have all rows summed together
SQL Server can use the DATEPART function.
SELECT DATEPART(MONTH, your_date_column) AS month_
, SUM(your_value) AS value_
FROM your_table
GROUP BY DATEPART(MONTH, your_date_column)
I have a table "Report" with relevant columns "Date", "Doctor". Each doctor appears several times throughout the table. The following code is what I have at current:
SET #variable = (SELECT Date FROM Report WHERE Doctor='DocName' ORDER BY Date DESC LIMIT 1)
SELECT DATEDIFF(CURDATE(),#variable) AS DiffDate
This gives me the DATEDIFF for one doctor, without name. Is there any way to loop through the table, find the last row/date for each doctor, then perform a DATEDIFF on each individual doctor outputting a list of doctors with their DATEDIFFs (against current date) next to them?
Thanks in advance!
you can use group by to get only 1 row per doctor and max to select latest date:
select `Doctor`, DATEDIFF(CURDATE(),max(`Date`))
from `Report`
group by `Doctor`
I am querying a database of hour entries and summing up by company and by week. I understand that MySQL's week function is based on a calendar week. That being said, I'm getting some unexpected grouping results. Perhaps you sharp-eyed folks can lend a hand:
SELECT * FROM (
SELECT
tms.date,
SUM( IF( tms.skf_group = "HP Group", tms.hours, 0000.00 )) as HPHours,
SUM( IF( tms.skf_group = "SKF Canada", tms.hours, 000.00 )) as SKFHours
FROM time_management_system tms
WHERE date >= "2012-01-01"
AND date <= "2012-05-11"
AND tms.skf_group IN ( "HP Group", "SKF Canada" )
GROUP BY WEEK( tms.date, 7 )
# ORDER BY tms.date DESC
# LIMIT 7
) AS T1
ORDER BY date ASC
My results are as follows: (Occasionally we don't have entries on a Sunday for example. Do null values matter?)
('date'=>'2012-01-01','HPHours'=>'0.00','SKFHours'=>'2.50'),
('date'=>'2012-01-02','HPHours'=>'97.00','SKFHours'=>'78.75'),
('date'=>'2012-01-09','HPHours'=>'86.50','SKFHours'=>'100.00'),
('date'=>'2012-01-16','HPHours'=>'68.00','SKFHours'=>'96.25'),
('date'=>'2012-01-24','HPHours'=>'39.00','SKFHours'=>'99.50'),
('date'=>'2012-02-05','HPHours'=>'3.00','SKFHours'=>'93.00'),
('date'=>'2012-02-06','HPHours'=>'12.00','SKFHours'=>'122.50'),
('date'=>'2012-02-13','HPHours'=>'64.75','SKFHours'=>'117.50'),
('date'=>'2012-02-21','HPHours'=>'64.50','SKFHours'=>'93.00'),
('date'=>'2012-03-02','HPHours'=>'45.50','SKFHours'=>'143.25'),
('date'=>'2012-03-05','HPHours'=>'62.00','SKFHours'=>'136.75'),
('date'=>'2012-03-12','HPHours'=>'54.25','SKFHours'=>'133.00'),
('date'=>'2012-03-19','HPHours'=>'77.75','SKFHours'=>'130.75'),
('date'=>'2012-03-26','HPHours'=>'61.00','SKFHours'=>'147.00'),
('date'=>'2012-04-02','HPHours'=>'86.75','SKFHours'=>'96.75'),
('date'=>'2012-04-09','HPHours'=>'84.25','SKFHours'=>'120.50'),
('date'=>'2012-04-16','HPHours'=>'90.00','SKFHours'=>'127.25'),
('date'=>'2012-04-23','HPHours'=>'103.25','SKFHours'=>'89.50'),
('date'=>'2012-05-02','HPHours'=>'72.50','SKFHours'=>'143.75'),
('date'=>'2012-05-07','HPHours'=>'68.25','SKFHours'=>'119.00')
January 2nd is the first Monday, hence Jan 1st is only one day. I would expect the output to be consecutive Mondays (Monday Jan 2, 9, 16, 23, 30, etc)? The unexpected week groupings below continue throughout the results. Any ideas?
Thanks very much!
It's not clear what selecting tms.date even means when you're grouping by some function on tms.date. My guess is that it means "the date value from any source row corresponding to this group". At that point, the output is entirely reasonable.
Given that any given group can have seven dates within it, what date do you want to get in the results?
EDIT: This behaviour is actually documented in "GROUP BY and HAVING with Hidden Columns":
MySQL extends the use of GROUP BY so that the select list can refer to nonaggregated columns not named in the GROUP BY clause.
...
The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate. Furthermore, the selection of values from each group cannot be influenced by adding an ORDER BY clause. Sorting of the result set occurs after values have been chosen, and ORDER BY does not affect which values the server chooses.
The tms.date column isn't part of the GROUP BY clause - only a function operating on tms.date is part of the GROUP BY clause, so I believe the text above applies to the way that you're selecting tms.date: you're getting any date within that week.
If you want the earliest date, you might try
SELECT MIN(tms.date), ...
That's assuming that MIN works with date/time fields, of course. I can't easily tell from the documentation.
Question is not clear for me but I guess you don't want to group by week. Because week gives week of year. which is 19th week today.
I think you want to group by Weekday like GROUP BY WEEKday(tms.date)
I have the following table structure:
ID, User_ID, DateTime
Which stores a user id and datetime of an order purchased. How would I get the average number of orders a day, across every row?
In pseudo code I'm thinking:
Get total number of orders
Get number of days in range (from first row to last row).
Divide 1. by 2. to get average?
So it would return me a value of 50, or 100?
Thanks
Since you know the date range, and you are not guaranteed to have and order on these dates, you can't just subtract the max(date) from min(date), but you know the number of days before you run the query, therefore simply:
select count(*) / <days>
from mytable
where DateTime between <start> and <end>
Where you supply the indicated values because you know them.
select DATEDIFF(NOW(), date_time) as days, AVG(count(*))
from table
group by days
I have not tested the query, its just the idea, I guess it should work.