Running an Access query on a FILTERED table - sql

I have some related tables that I want to run a Totals/Group By query on.
My "Tickets" table has a field called "PickDate" which is the date that the order/ticket was fulfilled.
I want to group by the weekday (name) (a calculated field) so that results for certain customers on the same day of the week are grouped. Then the average ticket completion time can be calculated per customer for each weekday. It would look something like the following.
--CustName---Day---AvTime
Customer 1 - MON - 72.3
- TUE - 84.2
- WED - 110.66
..etc
..etc
..etc
Customer 2 ..
This works fine but the problem I am having is that when this query is run, it works on every record from the tickets table. There are some reasons that, for certain reports, the data that it the query is referencing should be restricted between a date range; for example to track a change in duration over a number of weeks.
In the query properties, there is a property, "filter", to which I can add a string such as:
"([qryCustomerDetails].[PickDate] Between #11/1/2021# And #11/14/2021#)"
to filter the results. The only issue is that since each date is unique, the "group by" of like days such as "Monday" is overridden by this unique date "11/1/2021". The query only works when the PickDate is removed as a field. However, then I can't access it to filter by it.
What I want to achieve would be the same as; in the "Tickets" table itself filtering the results between two dates and then having a query that could run on that filtered table.
Is there any way that I could achieve this?
For reference here is the SQL of the query.
FROM tblCustomers INNER JOIN tblTickets ON tblCustomers.CustomerID = tblTickets.CustomerID
GROUP BY tblCustomers.Customer, WeekdayName(Weekday([PickDate]),False,1), tblCustomers.Round, Weekday([PickDate])
ORDER BY tblCustomers.Round, Weekday([PickDate]);

You probably encountered two issues. The first issue is that to filter results in a totals query by un totaled fields you use HAVING rather than WHERE. the second issue is that calculated fields like Day don't exist at the time of the query. You can't say having Day > Mon. Instead you must repeat the calculation of Day: Having CalculateDay(PickDate) > Monday
The designer will usually figure out whether you want having or where automatically. So here is my example:
this gives you the SQL:
SELECT Tickets.Customer, WeekdayName(Weekday([PickDate])) AS [Day], Avg(Tickets.Time) AS AvTime
FROM Tickets
GROUP BY Tickets.Customer, WeekdayName(Weekday([PickDate])), Tickets.PickDate
HAVING (((Tickets.PickDate) Between #11/16/2021# And #11/17/2021#))
ORDER BY Tickets.PickDate;

Related

How to get records month wise on rollover calender

I am using following query to get records count on month wise and it is working fine:
SELECT MONTH(dte_cycle_count) MONTH, COUNT(*) COUNT
FROM inventory
WHERE YEAR(dte_cycle_count)='2021' --OR (MONTH(dte_cycle_count) = '1' OR MONTH(dte_cycle_count) = '12')
GROUP BY MONTH(dte_cycle_count);
Problem:
Now I need to bind rollover calendar so user can scroll or click on next or previous button the next 12 Months record will be visible.
eg. Current month is MARCH, So default records will be from APR2020 to MARCH2021. If user click on previous then records will come MAR2020 to FEB2021.
How I can achieve this?
Please let me know if need more information. I will try my best to provide.
I think what you are after is a date list from which to join to your inventory table.
Like a numbers table, build a static table with columns for date, year, month, populated from whenever you need to far in the future.
You then select from this, applying your filtering range critera, and join to your inventory table.
For an efficient query, ideally your inventory table should have the relevant date portions eg year and month stored to match.
You don't want to be using functions on a datetime to extract the year or month as this is not sargable and will not allow any index to be used for a seek lookup.

SQL how to implement if and else by checking column value

The table below contains customer reservations. Customers come and make one record in this table, and the last day this table will be updated its checkout_date field by putting that current time.
The Table
Now I need to extract all customers spending nights.
The Query
SELECT reservations.customerid, reservations.roomno, rooms.rate,
reservations.checkin_date, reservations.billed_nights, reservations.status,
DateDiff("d",reservations.checkin_date,Date())+Abs(DateDiff("s",#12/30/1899
14:30:0#,Time())>0) AS Due_nights FROM reservations, rooms WHERE
reservations.roomno=rooms.roomno;
What I need is, if customer has checkout status, due nights will be calculated checkin_date subtracting by checkout date instead current date, also if customer has checkout date no need to add extra absolute value from 14:30.
My current query view is below, also my computer time is 14:39 so it adds 1 to every query.
Since you want to calculate the Due nights upto the checkout date, and if they are still checked in use current date. I would suggest you to use an Immediate If.
The condition to check would be the status of the room. If it is checkout, then use the checkout_date, else use the Now(), something like.
SELECT
reservations.customerid,
reservations.roomno,
rooms.rate,
reservations.checkin_date,
reservations.billed_nights,
reservations.status,
DateDiff("d", checkin_date, IIF(status = 'checkout', checkout_date, Now())) As DueNights
FROM
reservations
INNER JOIN
rooms
ON reservations.roomno = rooms.roomno;
As you might have noticed, I used a JOIN. This is more efficient than merging the two tables with common identifier. Hope this helps !

Aggregating 15-minute data into weekly values

I'm currently working on a project in which I want to aggregate data (resolution = 15 minutes) to weekly values.
I have 4 weeks and the view should include a value for each week AND every station.
My dataset includes more than 50 station.
What I have is this:
select name, avg(parameter1), avg(parameter2)
from data
where week in ('29','30','31','32')
group by name
order by name
But it only displays the avg value of all weeks. What I need is avg values for each week and each station.
Thanks for your help!
The problem is that when you do a 'GROUP BY' on just name you then flatten the weeks and you can only perform aggregate functions on them.
Your best option is to do a GROUP BY on both name and week so something like:
select name, week, avg(parameter1), avg(parameter2)
from data
where week in ('29','30','31','32')
group by name, week
order by name
PS - It' not entirely clear whether you're suggesting that you need one set of results for stations and one for weeks, or whether you need a set of results for every week at every station (which this answer provides the solution for). If you require the former then separate queries are the way to go.

Query to get Daywise on the month selected

I have an MS Access database table datetime column. When I select a particular month (say, July), I have to get datewise data in that month.
The output should appear in the same format as the attached image.
Every Employee who comes in on a particular date should display “P” for that day. If the Employee doesn’t come in on a particular day (like Sat or Sun), then I have to display “WO” for that day.
When an Employee has not come in (like Sat or Sun), then there is no entry in the log table for that date.
How could an Access query be written to obtain this output? I am using an MS Access 2003 database.
Edit: we have to use TRANSFORM and PIVOT, but the issue is when an employee is not available (Sat, Sun) we still need to show data in the output.
Set up a query that reads EmpID and CheckTime from the first table, and adds one additional column:
DateWise: IIf(Weekday([CheckTime])=1 Or Weekday([CheckTime])=7,"WO","P")
You will need an additional table with every date of the year in it (we'll call it YearDates). Left join that table to your query like so:
Select YD.YearDates, Q2.* from YearDates YD LEFT JOIN Query2 Q2 ON YD.YearDates = DATEVALUE(Q2.CheckTime)
The DATEVALUE will strip the time off your dates in CheckTime so they will match date against date.

PostgreSQL - GROUP BY timestamp values?

I've got a table with purchase orders stored in it. Each row has a timestamp indicating when the order was placed. I'd like to be able to create a report indicating the number of purchases each day, month, or year. I figured I would do a simple SELECT COUNT(xxx) FROM tbl_orders GROUP BY tbl_orders.purchase_time and get the value, but it turns out I can't GROUP BY a timestamp column.
Is there another way to accomplish this? I'd ideally like a flexible solution so I could use whatever timeframe I needed (hourly, monthly, weekly, etc.) Thanks for any suggestions you can give!
This does the trick without the date_trunc function (easier to read).
// 2014
select created_on::DATE from users group by created_on::DATE
// updated September 2018 (thanks to #wegry)
select created_on::DATE as co from users group by co
What we're doing here is casting the original value into a DATE rendering the time data in this value inconsequential.
Grouping by a timestamp column works fine for me here, keeping in mind that even a 1-microsecond difference will prevent two rows from being grouped together.
To group by larger time periods, group by an expression on the timestamp column that returns an appropriately truncated value. date_trunc can be useful here, as can to_char.