Query by month from date field - ms-access

I have a set of Access d/b's grouped already by year. within a given year, I have a field caleld REPORTDATE which is a standard mm/dd/yyyy field. However, I need to produce queries that return data by the month. For example, I just want to see records for Jan, recs for Feb, Recs for March, etc., so that I can sum them and work wwith thm.
Do I use an expression in the query design view Criteria field?
Thanks in advance.

I just want to see records for Jan, recs for Feb, Recs for March, etc., so that I can sum them and work wwith thm.
You can do all of that in one sql statement:
select month(reportdate), sum( the column you wish to sum )
from tablename
group by month(reportdate);
BUT WAIT THERE'S MORE!
Further say that there are several salepersons selling stuff, and you wish to show each salesperson's sales by month
select month(reportdate), salesperson, sum( the column you wish to sum )
from tablename
group by month(reportdate), salesperson;
That shows the sum per month per salesperson.
You know the Germans always make good stuff!
What it you wanted to see the same sums, but rtaher than comparing salespeople against each other in each month, you wanted to compare, for each salesperson, how they did from one month to another?
Just reverse the order of the group by:
select month(reportdate), saleperson, sum( the column you wish to sum )
from tablename
group by salesperson, month(reportdate);
Tacos, Fettuccini, Linguini, Martini, Bikini, you're gonna love my nuts!
The power of SQL! As seen on TV! Order now!
"select month(reportdate), sum( the column you wish to sum )from tablenamegroup by month(reportdate);" THIS IS VERY HELPFUL, THANK YOU. AND YOU ARE HILARIOUS. HOWEVER, can you clarify for me where the heck this code goes?! In the expresison Builder or what? Thank you SO much. – rick (19 mins ago)
In Access, I think from the graphical Query Builder thing's menu, select edit|SQL, and just type. And never go back to graphical!
You're a hard-charging forward-thinking entrepreneurially-minded man on the move! This is not your father's Oldsmobile! You wouldn't use an on-screen keyboard to type a document, dragging and dropping letters on the page, would you?! So why do that to build a SQL Query? Get into SQL! AS SEEN ON TV! All the cool kids and hep cats are doin' it! Order NOW!

You can use format, for example:
Format([REPORTDATE],"mmm yy")
Or Month:
SELECT * FROM Table WHERE Month([REPORTDATE]) = 10
An outline of query that may suit, paste this into the SQL view of
the query design window, changing table to the name of your table:
SELECT Format([REPORTDATE],"yyyy mm"), Count([ReportDate])
FROM Table
GROUP BY Format([REPORTDATE],"yyyy mm")

I wouldn't do this in the report's recordsource. I'd make the recordsource a regular SELECT statement and use the report's sorting/grouping. If you group on a date field (one that is really date type), you get the choice to GROUP ON:
Each Value (default)
Year
Qtr
Month
Week
Day
Hour
Minute
I think this is faster than a GROUP BY on a function, but someone who was interested should actually try it.
Certainly if your SELECT with GROUP BY has no WHERE clause, it's going to be a lot more efficient if you run the report with filtered values.

Related

I'm stock with a SQL statement, about getting the right amount

I am so sorry if there is already an answer for this question, I just haven't been able to find it.
I am making a little chart to my home systems, which is a overview of my savings, I already have a chart showing how much is going in each months.
This is the SQL statement I have managed to get working so far
SELECT SUM(amount) AS total, DATE(dt) AS `date` FROM `savings` GROUP BY MONTH(`date`)
Which gives this result:
SQL result image
But this is not fully what I am doing to get, since this statement gives an amount for each month, what I need is one that add to the last amount, so that I can see the full amount of saving over months, if that makes sense?
It sounds like you want WITH ROLLUP:
SELECT SUM(amount) AS total, EXTRACT(YEAR_MONTH FROM dt) AS `yearmonth`
FROM `savings`
GROUP BY yearmonth WITH ROLLUP;
This does your grouping by year/month, plus adds one more row to the result set, with the total. The yearmonth column will be returned as NULL on that rollup row.

Calculate AVG base on dayweek SQL

I'm working whit a MariaDB database.
I need to know, for every day in a certain time the avg of a count.
I'd tried somethink like this.
SELECT AVG(dayShipments), weekdays
FROM (SELECT COUNT(idShipment) as "dayShipments", WEEKDAY(dateShipments) as "weekdays"
FROM weekdays
WHERE dateShipments BETWEEN '2021-05-01'AND '2021-05-21'
GROUP BY dateShipments) as t1
GROUP BY weekdays
My boss told me that this query ignore the day where I don't have any Shipment.
How can i inlude that?
Sorry for my bad English and thanks for helping me
If you want to summary by day-of-the-week (which is what your query appears to be doing. And you want to treat days with no shipments as 0, then use SUM() and division:
SELECT WEEKDAY(dateShipments) as weekday,
COUNT(*) / 3 as dayShipments as avg_per_day
FROM weekdays
WHERE dateShipments BETWEEN '2021-05-01'AND '2021-05-21'
GROUP BY weekday;
The 3 is because the query spans three weeks.
First of all don't worry about your english. It's good enough.
Secondly, your boss is right. If you have no records in "weekdays" table for specific day, the mentioned day will never show up with this query.
For solving problem I think you need to have a temporary table for day of week and left join with your t1 table.

MySQL Group By Order and Count(Distinct)

What is the best way to think about the Group By function in MySQL?
I am writing a MySQL query to pull data through an ODBC connection in a pivot table in Excel so that users can easily access the data.
For example, I have:
Select
statistic_date,
week(statistic_date,4),
year(statistic_date),
Emp_ID,
count(distict Emp_ID),
Site
Cost_Center
I'm trying to count the number of unique employees we have by site by week. The problem I'm running into is around year end, the calendar years don't always match up so it is important to have them by date so that I can manually filter down to the correct dates using a pivot table (2013/2014 had a week were we had to add week 53 + week 1).
I'm experimenting by using different group by statements but I'm not sure how the order matters and what changes when I switch them around.
i.e.
Group by week(statistic_date,4), Site, Cost_Center, Emp_ID
vs
Group by Site, Cost_Center, week(statistic_date,4), Emp_ID
Other things to note:
-Employees can work any number of days. Some are working 4 x 10's, others 5 x 8's with possibly a 6th day if they sign up for OT. If I sum the counts by week, I get anywhere between 3-7 per Emp_ID. I'm hoping to get 1 for the week.
-There are different pay code per employee so the distinct count helps when we are looking by day (VTO = Voluntary Time Off, OT = Over Time, LOA = Leave of Absence, etc). The distinct count will show me 1, where often times I will have 2-3 for the same emp in the same day (hits 40 hours and starts accruing OT then takes VTO or uses personal time in the same day).
I'm starting with a query I wrote to understand our paid hours by week. I'm trying to adapt it for this application. Actual code is below:
SELECT
dkh.STATISTIC_DATE AS 'Date'
,week(dkh.STATISTIC_DATE,4) as 'Week'
,month(dkh.STATISTIC_DATE) as 'Month'
,year(dkh.STATISTIC_DATE) as 'Year'
,dkh.SITE AS 'Site ID Short'
,aep.LOC_DESCR as 'Site Name'
,dkh.EMPLOYEE_ID AS 'Employee ID'
,count(distinct dkh.EMPLOYEE_ID) AS 'Distinct Employee ID'
,aep.NAME AS 'Employee Name'
,aep.BUSINESS_TITLE AS 'Business_Ttile'
,aep.SPRVSR_NAME AS 'Manager'
,SUBSTR(aep.DEPTID,1,4) AS 'Cost_Center'
,dkh.PAY_CODE
,dkh.PAY_CODE_SHORT
,dkh.HOURS
FROM metrics.DAT_KRONOS_HOURS dkh
JOIN metrics.EMPLOYEES_PUBLIC aep
ON aep.SNAPSHOT_DATE = SUBDATE(dkh.STATISTIC_DATE, DAYOFWEEK(dkh.STATISTIC_DATE) + 1)
AND aep.EMPLID = dkh.EMPLOYEE_ID
WHERE dkh.STATISTIC_DATE BETWEEN adddate(now(), interval -1 year) AND DATE(now())
group by dkh.SITE, SUBSTR(aep.DEPTID,1,4), week(dkh.STATISTIC_DATE,4), dkh.STATISTIC_DATE, dkh.EMPLOYEE_ID
The order you use in group by doesn't matter. Each unique combination of the values gets a group of its own. Selecting columns you don't group by gives you somewhat arbitrary results; you'd probably want to use some aggregation function on them, such as SUM to get the group total.
Grouping by values you derive from other values that you already use in group by, like below, isn't very useful.
week(dkh.STATISTIC_DATE,4), dkh.STATISTIC_DATE
If two rows have different weeks, they'll also have different dates, right?

Trying to figure out SQL query for monthly user churn based on an activity threshold

I have a table (we're on InfoBright columnar storage and I use MySQL Workbench as my interface) that essentially tracks users and a count of activities with a datestamp. It's a daily aggregate table. Schema is essentially
userid (int)
activity_count (int)
date (date)
What I'm trying to find is how many of my users are churning from month to month, with a basis of an active user defined as one with a monthly activity count that sums up to > 10
To find how many users are active in a given month I am currently using
select year, month, count(distinct user) as users
from
(
select YEAR(date) as year, MONTH(date) as month, userid as user, sum(activity_count) as activity
from table
group by YEAR(date), MONTH(date), userid
having activity > 10
order by YEAR(date), MONTH(date)
) t1
group by year, month
Not being a SQL expert, I am sure this can be improved and would appreciate the input on that.
My bigger goal though is to figure out from month to month, how many of the users who are in this count are new or repeat from the previous month. I don't know how to do that without what feels like ugly nesting or joining, and I feel like it should be fairly simple.
Thanks in advance.
I think that further nesting is the best way to achieve this. I would look to do something like selecting the user for the min concatenated Year & Month as a middle layer to the above (i.e. between outer and inner queries) so that you can establish the first month that the user became active. You can then add a where clause to the outer query to filter so that only the months you require are showing. Let me know if you need help with the syntax.

Filter weekly from daily data and pick first occurence of the week

Assume you have a table with a stock time series on a daily basis.
Now you need to filter one data point per week, because you need weekly data for some analysis. You don't to have weekly averages, since this would leave much of the variation out.
This would be my initial approach, but it's not clear which of the data points falling in a given week is selected.
SELECT date, price from stock_series
GROUP BY WEEK(date)
1 How do I make sure it's always the first data point existing for a given week that gets picked?
EDIT:
2 If the above query stayed the way it is - which data point gets chosen every week? What's the MySQL logic in this case? Or is it just unpredictible?
If you want to have a better control over it, you could try using a subquery :
SELECT date,price
FROM stock_series
WHERE date IN
(
SELECT MIN(inner.date)
FROM stock_series inner
GROUP BY WEEK(inner.date)
) GROUP BY date
I've added GROUP BY date in the main query because you probably have more than one entry per day, otherwise it could be ommited.
EDIT:
or try joining with it:
SELECT date,price
FROM stock_series
JOIN
(
SELECT MIN(date) AS innerdate
FROM stock_series
GROUP BY WEEK(date)
) inner ON date=innerdate;
You can order by date ascending, which should give you just the first result of the WEEK() group.
SELECT date,price from stock_series
GROUP BY WEEK(date)
ORDER BY date