I have a working query which takes too long to run. It is being used to populate an Access form field with a list of distinct contracts ordered by their start date.
The following query returns a list of distinct contract start dates for multiple commodities (which share contract start dates) where the contract start date (DELSTART) is greater or equal to the current date (PRICEDATE).
The function returndelivery returns a date attribute of the contract converted to a double, the function returnnumericdate just returns a double from a date (yyyymmdd).
SELECT DISTINCT (tblFuturesPrices.Period),
returnnumericdate(returndelivery([PERIOD],"S")) AS DELSTART,
ReturnNumericDate(Date()) AS PRICEDATE
FROM tblFuturesPrices
WHERE returnnumericdate(returndelivery([PERIOD],"S")) >= ReturnNumericDate(Date())
GROUP BY PERIOD
ORDER BY returnnumericdate(returndelivery([PERIOD],"S"));
Ideally I would like to refer to the variables DELSTART and PRICEDATE in the where clause but Access prompts for a variable value when I do so. I think the query takes longer than it should because I'm having to use my user defined functions numerous times.
The source table (tblFutures) contains prices for each commodity / contract for working days going back 6 months.
Thanks in advance.
I think the query takes longer than it should because I'm having to
use my user defined functions numerous times.
That's it. But you can reduce those functions:
returnnumericdate(returndelivery([PERIOD],"S")) >= ReturnNumericDate(Date())
will be no different from
returndelivery([PERIOD],"S") >= Date()
Don't know what returndelivery does.
Addendum:
Filter on the raw data and create a new function returndeliverydate that does the same as returndelivery except returns a Date value:
SELECT
tblFuturesPrices.Period,
returndeliverydate([PERIOD],"S") AS DELSTART,
Date() AS PRICEDATE
FROM
tblFuturesPrices
WHERE
returndeliverydate([PERIOD],"S") >= Date()
Save this query and use it as source in a new query:
Select Distinct
DELSTART,
PRICEDATE
FROM
YourQuery
Related
what command should I use to make an output based on this problem:
Display the all values of customers who have joined as members for more than 700 days until today
This is the table that I have created:
table Customers
I've tried other references using DATEDIFF(), but it's always invalid :
SELECT * FROM Customers where DATEDIFF(DAY,customer_join,GETDATE())>700;
In MySQL/MariaDB, as opposed to SQL Server, DATEDIFF() takes just two arguments, and returns an integer number of days between them. We have timestampdiff(), which takes three arguments.
Also, getdate() is not a thing in MySQL (this is a bespoke SQL Server function).
You don't really need date functions here. I would phrase this logic using simple data arithmetics:
select *
from customers
where customer_join < current_date - interval 700 day
This expression can take advantage of an index on customer_join.
Depending on whether you want to take in account the time portion of customer_join (if it has one), you might want to use now() instead of current_date.
How to bulid a query in Ms Access to include the day before amounts as an opening balance. So on running the query i enter 3/10/18 in the WorkDay parameter box and records for 3/10/18 and 2/10/18 is shown. The Table is setup as follows:
WorkDay....TranactionID....Amount
2/10/18......Opening........1000
2/10/18......Credit.........500
2/10/18.......Debit.........300
3/10/18.......Credit........700
3/10/18.......Debit.........200
So if I run the query for 3/10/18 it should return
WorkDay....TranactionID....Amount
2/10/18......[Expr].........800
3/10/18.......Credit........700
3/10/18.......Debit.........200
If you are using the GUI add DateAdd("d",-1,[MyDateParameter]) to the OR line under [MyDateParameter] in the Workday field.
For SQL WHERE statement you would use
WorkDay=[MyDateParameter] OR Workday=DateAdd("d",-1,[MyDateParameter])
Obviously substitute [MyDateParameter] with whatever your date parameter actually is.
First some notes about the request:
The desired results imposes different requirements for the current day vs the previous day, so there must be two different queries. If you want them in one result set, you would need to use a UNION.
(You could write a single SQL UNION query, but since UNION queries do not work at all with the visual designer, you are left to write and test the query without any advantages of the query Design View. My preference is therefore to create two saved queries instead of embedded subqueries, then create a UNION which combines the results of the saved queries.)
Neither the question, nor answers to comments indicate what to do with any exceptions, like missing dates, weekends, etc. The following queries take the "day before" literally without exception.
The other difficulty is that the Credit entries also have a positive amount, so you must handle them specially. If Credits were saved with negative values, the summation would be simple and direct.
QueryCurrent:
PARAMETERS [Which WorkDay] DateTime;
SELECT S.WorkDay, S.TransactionID, Sum(S.[Amount]) As Amount
FROM [SomeUnspecifiedTable] As S
WHERE S.WorkDay = [Which WorkDay]
GROUP BY S.WorkDay, S.TransactionID
QueryPrevious:
PARAMETERS [Which WorkDay] DateTime;
SELECT S.WorkDay, "[Expr]" As TransactionID,
Sum(IIF(S.TransactionID = "Credit", -1, 1) * S.[Amount]) As Amount
FROM [SomeUnspecifiedTable] As S
WHERE S.WorkDay = ([Which WorkDay] - 1)
GROUP BY S.WorkDay
Union query:
SELECT * FROM QueryCurrent
UNION
SELECT * FROM QueryPrevious
ORDER BY [WorkDay]
Notes about the solution:
You could also use DateAdd() function, but add/subtracting integers from dates defaults to a change of days.
I'm a receptionist keeping track of incoming calls in MS-Access 2010. The table has Date column. I can get count of calls per day but am having trouble with SQL to get average calls per day.
Assuming your table has one record per call, you can use a query like this, just replace the table and field names:
SELECT Avg(TotalCalls.DailyCalls) AS AverageCalls
FROM
(
SELECT MyTable.MyDateField, Count(MyTable.MyDateField) AS DailyCalls
FROM MyTable
WHERE MyDate > #1-Feb-2017# AND MyDate <= #28-Feb-2017#
GROUP BY MyTable.MyDateField
) AS TotalCalls
This won't take into account days that have no calls, just the ones that do. The WHERE clause is optional, but you might want to use that to pick a specific date range.
Im trying to make a small report for myself to see how my much time I get inputed in my system every day.
The goal is to have my SQL to sum up the name, Total time worked and Total NG product found for one specific day.
In this order:
1.) Sort out my data for a specific 'date'. I.E 2016-06-03
2.) Present a DISTINCT value for 'operators'
3.) SUM() all time registered at this 'date' and by this 'operator' under 'total_working_time_h'
4.) SUM() all no_of_defects registered at this 'date' and by this 'operator' under 'no_of_defects'
date, operator, total_working_time_h, no_of_defects
Currently I get the data I want by using the Query below. But now I need both the DISTINCT value of the operator and the SUM of the information. Can I use sub-queries for this or should it be done by a loop? Any other hints where I can learn more about how to solve this?
If i run the DISTINCT function I don't get the opportunity to sum my data the way I try.
SELECT date, operator, total_working_time_h, no_of_defects FROM {$table_work_hours} WHERE date = '2016-06-03' "
Without knowing the table structure or contents, the following query is only a good guess. The bits to notice and work with are sum() and GROUP BY. Actually syntax will vary a bit depending on what RDBMS you are using.
SELECT
date
,operator
,SUM(total_working_time_h) AS total_working_time_h
,SUM(no_of_defects) AS no_of_defects
FROM {$table_work_hours}
WHERE date = '2016-06-03'
GROUP BY
date
,operator
(Take out the WHERE clause or replace it with a range of dates to get results per operator per date.)
I'm not sure why you are trying to do DISTINCT. You want to know the data, no of hours, etc for a specific date.
do this....
Select Date, Operator, 'SumWorkHrs'=sum(total_working_time_h),
'SumDefects'=sum(no_ofDefects) from {$table_work_hours}
Where date='2016-06-03'
Try this:
SELECT SUM(total_working_time) as total_working_time,
SUM(no_of_defects) as no_of_defects ,
DISTINCT(operator) AS operator FROM {$table_work_hours} WHERE
date = '2016-06-03'
I have the following Access query (see above) to give me the date, X number of weeks out from the actual WorkDte that exists in the table. But, the date these expressions calculate out may not actually exists in the “CIB_Results” table due to a bank holiday etc. Is there a way to generate the same sort of data but say if it’s running the “Wk1” calculation and it calculates out 1/1/2016 (which does not exists due to the new year holiday), instead of doing [WorkDte]-7 it will move on to [WorkDte]-14 and so on, until it finds an actual date that exists in the “CIB_Results” table? I’m wanting to apply the same logic to all the fields in the query…that way they will all self adjust based off of the actual dates that exist in the “CIB_Results” table. Any help with this would be greatly appreciated!
Have a function IsHoliday(SomeDate) that looks up SomeDate in your holiday table and returns True if found.
Then create a loop:
Public Function PreviousWorkWeekday(ByVal SomeDate As Date) As Date
Do
SomeDate = DateAdd("ww", -1, SomeDate)
Loop Until Not IsHoliday(SomeDate)
PreviousWorkWeekday = SomeDate
End Function
Now use function PreviousWorkWeekday in your query.