I have a query that attaches dates to records, and I want the query to only return records whose newly attached dates are within the range of my input parameters.
In the Criteria block:
Between [StartDate] And [EndDate] does not work.
while...
Between #6/1/17# And #10/1/17# does work.
I assume it has to be a formatting issue, but don't know where to go from here. How can I marry the two (my calculated date and the input date parameters) fields so they compare correctly?
The SQL follows, I've copied the http://www.allenbrowne.com/ser-62.html sample database with plans to tweak it as needed.
PARAMETERS StartDate DateTime, EndDate DateTime;
SELECT qryCoreEventCartesian.EventID, qryCoreEventCartesian.InstanceID, DateAdd([qryCoreEventCartesian]![PeriodTypeID],[qryCoreEventCartesian]![InstanceID]*[qryCoreEventCartesian]![PeriodFreq],[qryCoreEventCartesian]![BeginDate]) AS EventDate, qryCoreEventCartesian.PID, qryCoreEventCartesian.Type, qryCoreEventCartesian.Comments, qryCoreEventCartesian.BeginDate, qryCoreEventCartesian.RecurCount, qryCoreEventCartesian.PeriodFreq, qryCoreEventCartesian.PeriodTypeID
FROM ltPeriodType INNER JOIN qryCoreEventCartesian ON ltPeriodType.PeriodTypeID = qryCoreEventCartesian.PeriodTypeID
WHERE (((DateAdd([qryCoreEventCartesian]![PeriodTypeID],[qryCoreEventCartesian]![InstanceID]*[qryCoreEventCartesian]![PeriodFreq],[qryCoreEventCartesian]![BeginDate])) Between [StartDate] And [EndDate]))
ORDER BY DateAdd([qryCoreEventCartesian]![PeriodTypeID],[qryCoreEventCartesian]![InstanceID]*[qryCoreEventCartesian]![PeriodFreq],[qryCoreEventCartesian]![BeginDate]);
Related
I have one sql query in which i have user timezone in which i have to retrieve date and time. Means i have to convert date and time to specific user_timezone. As per doc CONVERT_TZ() this function required from_timezone and to_timezone but i have only to_timezone parameter so how can i convert user date and time to specific time zone using mysql query. Below is the my sql query in which i need to implement.
So can anyone help me to resolve this issue ?
SELECT cpv.*, DATE_FORMAT(watchStartTime, '%Y-%m-%dT%H:%i:%s.000Z') as watchStartTime, DATE_FORMAT(watchEndTime, '%Y-%m-%dT%H:%i:%s.000Z') as watchEndTime, DATE(watchStartTime) as watchDate, DAYNAME(watchStartTime) as watchDay FROM ClientProgramVideo AS cpv LEFT JOIN ClientProgramMapping AS cpm ON cpm.id = cpv.clientProgramMappingId LEFT JOIN User AS u ON u.id = cpm.clientId WHERE u.sub = '8851de3e-459a-9a84-51ce99f83284' AND cpv.isCompleteWatch = 1 AND cpv.watchStartTime > '2021-04-20T07:10:03.000Z' GROUP BY DATE(watchStartTime) ORDER BY cpv.watchStartTime DESC;
In above query i need to convert timezone form "watchStartTime" and watchEndTime
I have couple of tables
Movements
Entries
and want to get the stock balance of items up to a given date. So I created queries and INNER JOINED to make a single table so it is easy to get the balance. This program is saved in a SP called
StblAsAt(IN RefDate DATE,IN Store VARCHAR,OUT #STBL DOUBLE)
However when I user the date format in the body as appears in the following line it works fine.
purchaseinvoice.invoiceDate<='2021-08-30'
But when it is changed to use the parameter, it returns zero (0). No matter what date I pass.
This is my code as it is in Stored Procedure
BEGIN
SELECT (Purchase+SalesReturns+TransferIn)-(PurchaseReturns+Sales+TransferOut) INTO #STBL FROM(
SELECT COALESCE(P.Purchase,0)AS 'Purchase',
COALESCE(Sr.SalesReturn,0)AS 'SalesReturns',
COALESCE(Ti.TransferIn,0)AS 'TransferIn',
COALESCE(Pr.PurchaseReturns,0)AS 'PurchaseReturns',
COALESCE(S.Sales,0) AS 'Sales',
COALESCE(Tout.TransferOut,0)AS 'TransferOut'
FROM(
(SELECT
'OTHRMA1032' AS 'Item',
SUM(movement.itemQty) AS 'Purchase'
FROM movement
WHERE
movement.movementType=0 AND
movement.entryDate<=DATE_FORMAT(#RefDate,'%Y-%m-%d')AND #Tried #RefDate and it fails
movement.itemId='OTHRMA1032' AND
movement.reference2 IN(
SELECT purchaseinvoice.GRNId
FROM purchaseinvoice
WHERE
purchaseinvoice.invoiceDate<=DATE_FORMAT(#RefDate,'%Y-%m-%d') AND
purchaseinvoice.inwardStore='Main store'
))P
(Didn't include all queries as it would make the post junk)
This is how I call the procedure from MySql
CALL StblAsAt('2021-08-30','Main store',#STBL);
Whenever the parameter is used, it returns zero and when the date is typed in, it returns the correct value.
I'm new to Python and PyMySQL, so I may have something misconfigured.
I'm connecting to MySQL without any problems. I tested it doing a SELECT and a DESC on a table, and was able to view the results.
I now have a query that I substitute date parameters into and want returned the count of a column (customers) and the total number of customers multiplied times a value.
The count of customers comes back correctly, but the product calculation returns None. Before executing the query, I print it to the console and copy that to MySQLWorkbench to run, and the correct values are returned.
In my main module I connect to the DB and get a cursor. I then get date values to use in the query and call the function that executes the query.
connection = dbConnection()
cursor = connection.cursor()
startDate = input("enter start date (yyyy-mm-dd): ").strip()
endDate = input("enter end date (yyyy-mm-dd): ").strip()
my_queries.queryTotals(cursor, startDate, endDate)
connection.close()
In my my_queries module I have the query and substitute the entered dates into the query string, then execute the query and fetch the results:
totalsSQL = '''select
#total:=count(cus.customer_id) as customers, format(#total * 1.99, 2) as total
from customer cus
join membership mem on mem.membership_id=cus.current_membership_id
where mem.request='START'
and (mem.purchase_date > (unix_timestamp(date('{}'))*1000) and mem.purchase_date < unix_timestamp(date('{}'))*1000);'''
formattedSQL = totalsSQL.format(startDate, endDate)
cursor.execute(formattedSQL)
result = cursor.fetchone()
I get a result of (32, None) as opposed to getting a numeric value for the 2nd column value.
What am I missing here?
Thanks.
You can't use a variable for an aggregate function, and refer to it later in the same SELECT list. Aggregates don't get their values until all the rows have been selected, but other columns are calculated while selecting rows.
Just use COUNT(*) in both places.
SELECT COUNT(*) AS customers, FORMAT(COUNT(*) * 1.99, 2) AS total
join membership mem on mem.membership_id=cus.current_membership_id
where mem.request='START'
and (mem.purchase_date > (unix_timestamp(date('{}'))*1000)
and mem.purchase_date < unix_timestamp(date('{}'))*1000)
Also, to prevent SQL injection you should use a parametrized query instead of substituting variables with format().
totalsSQL = '''
SELECT COUNT(*) AS customers, FORMAT(COUNT(*) * 1.99, 2) AS total
join membership mem on mem.membership_id=cus.current_membership_id
where mem.request='START'
and (mem.purchase_date > (unix_timestamp(date(%s))*1000)
and mem.purchase_date < unix_timestamp(date(%s))*1000)
'''
cursor.execute(totalsSQL, (startDate, endDate))
I've got a use case where I need to query for Appointment records based on their created_at or their start_on values. There are two types of appointments: 'Estimate' and 'GLA (go look at)', represented by a type field with values 0 and 1.
If the appointment is of type Estimate, the query needs to use the start_on field - and if the appointment is a GLA, the query needs to use the created_at field, as GLA's are not scheduled and don't have start_on values.
Right now, I'm querying the data using a Rails scope to filter down properties who've had their last appointment from and to a certain date like so (the following shows 'from'):
scope :last_appointment_from, ->(date, type) {
query = joins(:appointments)
query = query.where('appointments.start_on = (
SELECT MAX(appointments.start_on)
FROM appointments
WHERE appointments.property_id = properties.id)')
query = query.where('appointments.start_on >= ?', date)
query
}
But this only queries the start_on value.
I've tried looking into doing GREATEST(MAX(start_on), MAX(created_at)) - but then I'm not sure how to know which field to know to use in the where('events.start_on >= ?', date) part.
After typing this out, I thought of another possible workaround - to just create another database field that gets updated with the corresponding date on an active record callback based on what type of Appointment it is, called query_field or something (and run a script to set that value for all existing records) - and that way I can just query on that one field?
Any thoughts/help is greatly appreciated!
Since you already have a type field, it could be a use case for STI, i.e. same SQL schema for the model but different behavior on the ruby side.
Note the "type" field may already be causing issues with rails that you may not have considered as this field generally is reserved specifically for Single Table Inheritance STI in rails.
If you use STI you could just write an accessor that pulls the correct field from the database and presents it for each model.
I think this approach should work assuming that no appointment should have a created_at before its start_on unless it is GLA
scope :last_appointment_from, ->(date, type) {
query = joins(:appointments)
query = query.where('GREATEST(appointments.start_on, appointments.created_at) = (
SELECT GREATEST(MAX(start_on), MAX(created_at))
FROM appointments
WHERE appointments.property_id = properties.id)')
query = query.where('GREATEST(appointments.start_on, appointments.created_at) >= ?', date)
query
}
I'm not very good with Rails but for the pure MySQL you could use a where like this:
WHERE (
(appointments.created_at > date
AND appointments.type = 1)
OR
(appointments.start_on > date
AND appointments.type = 0)
)
I am trying to determine the count of attendance for a training course between 2007-2013. I need it to pull the employees job group they were in during the time frame:
SELECT O867IA_VJOBHST.JOB_CLS_CD, O867IA_VJOBHST.DIS_NR,
Sum(IIf(emp_tng_stt_dt Between #1/1/2007# And #12/31/2011#,1,0)) AS [2007-2011],
Sum(IIf(emp_tng_stt_dt Between #1/1/2011# And #12/31/2011#,1,0)) AS 2011,
Sum(IIf(emp_tng_stt_dt Between #1/1/2012# And #12/31/2012#,1,0)) AS 2012,
Sum(IIf(emp_tng_stt_dt Between #1/1/2013# And #9/23/2013#,1,0)) AS 2013, O867IA_VJOBHST.REC_EFF_STT_DT, O867IA_VTRAING.EMP_TNG_STT_DT
FROM (O867IA_VJOBHST INNER JOIN O867IA_VTRAING ON O867IA_VJOBHST.SYS_EMP_ID_NR = O867IA_VTRAING.SYS_EMP_ID_NR) INNER JOIN O867IA_VPJOBCO ON O867IA_VJOBHST.JOB_CLS_CD = O867IA_VPJOBCO.JOB_CLS_CD
WHERE (((O867IA_VTRAING.REG_NR)="03") AND ((O867IA_VTRAING.TNG_SYS_NR)="0918") AND ((O867IA_VPJOBCO.JOB_GRP_CD)="61"))
GROUP BY O867IA_VJOBHST.JOB_CLS_CD, O867IA_VJOBHST.DIS_NR, O867IA_VJOBHST.REC_EFF_STT_DT, O867IA_VTRAING.EMP_TNG_STT_DT;
The REC_EFF_STT_DT field is the date they were recorded in their job, so I am trying to get that to be the MAX date, and it needs to be less than EMP_TNG_STT_DT which is when the training course was held. I try set it up like (((O867IA_VJOBHST.REC_EFF_STT_DT)<[O867IA_VTRAING].[EMP_TNG_STT_DT])); but it keeps giving me an error "you tried to execute a query that does not include the specified expression" whenever I add the MAX to REC EFF STT DT. I cannot find any solutions and need assistance.
If your ((MAX(O867IA_VJOBHST.REC_EFF_STT_DT) < [O867IA_VTRAING].[EMP_TNG_STT_DT])) is giving you this error, then perhaps it is also in your SELECT list, and is not just a 'Whereclause. Try removing it from yourSELECT` list.
Another suggestion is that [O867IA_VTRAING].[EMP_TNG_STT_DT] is not aggregated. You may be able to get this to work by aggregating that too. If you want the unaltered value, a FIRST() may work.