Why did this query change work? - ms-access

I ended up scrapping the part of the WHERE clause that was giving me issues, but initially I got this query working by doing something that didn't make sense to me at all, and was hoping someone could shine some light on what is going on here. The entire query and function are below, but I'm not sure all of that is necessary
So this query was previously working and this WHERE clause is still being used successfully in another query. Now multiple functions are used in this line of the where clause, however if I just use the portion starting with ModifiedStartDate the query works fine. So it seems like the issue is with ModifiedDate. The portion of the WHERE clause that was giving us issues was:
and ModifiedDate(r.EXPIRATION_DATE, ModifiedStartDate(r.COMMENCEMENT_DATE,
PaySched_MaxFreq(r.RE_CONTRACT_KEY))) > #1/1/2019#
The query was failing with the error "Data type mismatch in criteria expression". So just doing some testing I ended up adding the following portion to the WHERE clause:
and r.RE_CONTRACT_KEY NOT IN (1)
And then the query worked?!?! I really don't get how adding this line magically resolved a data type mismatch error. There is no RE_CONTRACT_KEY = 1 so it's not bad data or something.
I did some testing and took the ModifiedDate function and put that into the select clause and it worked fine. I also added another field to the SELECT clause using the DATEADD function to make sure the function result was still being treated as a date, and it was. Query is below and the function is below that.
SELECT DISTINCT ....
FROM ((((((PAYMENT_LINE_ITEM AS pli
INNER JOIN PAYMENT_SCHEDULE AS tps ON pli.PAYMENT_SCHEDULE_KEY =
ps.PAYMENT_SCHEDULE_KEY)
INNER JOIN RECONTRACT AS r ON pli.RE_CONTRACT_KEY = r.RE_CONTRACT_KEY)
INNER JOIN Conversion_ProductCategory AS cpc ON cpc.Value = pli.PAYMENT_TYPE)
INNER JOIN ManualEntry AS me ON me.LeaseID = r.RE_CONTRACT_ID)
LEFT JOIN Mapping_CostCenter AS mcc ON mcc.CostCenter = me.CostCenter)
INNER JOIN PIW_Exclusions AS pe ON pe.RE_CONTRACT_ID = r.RE_CONTRACT_ID)
LEFT JOIN FacilityCode_Address_xRef AS fca ON fca.[Facility Code] =
mcc.placecode & "-" & mcc.placecodedescription
WHERE pli.PAYMENT_TYPE in ("rent","storage","parking")
and ModifiedDate(r.EXPIRATION_DATE,
ModifiedStartDate(r.COMMENCEMENT_DATE,
PaySched_MaxFreq(r.RE_CONTRACT_KEY))) > #1/1/19#
and PE.Reason = "rent extension"
and r.RE_CONTRACT_KEY NOT IN (1) 'New line added that made query work
And the function:
Public Function ModifiedDate(DateToModify As Date, DateToCompare As Date) As
Date
Select Case DateToModify
Case #2/28/2000#, #2/28/2004#, #2/28/2008#, #2/28/2012#, #2/28/2016#,
#2/28/2020#, #2/28/2024#, #2/28/2028#, #2/28/2032#, #2/28/2036#, #2/28/2040#,
#2/28/2044#, #2/28/2048#
DateToModify = DateAdd("d", 1, DateToModify)
End Select
If DatePart("d", DateAdd("d", 1, DateToModify)) = DatePart("d",
DateToCompare) Then
ModifiedDate = DateAdd("d", 1, DateToModify)
Else
ModifiedDate = DateToModify
End If
End Function
If you're curious the final working WHERE clause is:
WHERE pli.PAYMENT_TYPE in ("rent","storage","parking")
and r.EXPIRATION_DATE > #1/1/19#
and PE.Reason = "rent extension"

Related

MYSQL Inner Join with Criteria

I have a MySQL Command and it looks like this
UPDATE Variance as VAR INNER JOIN receiving as REV ON (VAR.ItemCode = REV.ItemCode)
SET VAR.Receiving = REV.QtyPack * REV.PCS + REV.QtyStan;
and its working perfectly.
now my question here is how can I apply this criteria to mysql command?
1.Receiving.Date is Between 2 Dates
2.Receiving.Status = "Posted"
3.If Receiving.QtyPack and Receiving.QtyStan = "0" or "NULL" then Var.Receiving will become "0"
I hope you dont downvote this.
Please do not hesitate to ask question or clarification and I will edit my post
I think you can just add the conditions directly into the query:
UPDATE Variance VAR INNER JOIN
receiving REV
ON VAR.ItemCode = REV.ItemCode
SET VAR.Receiving = COALESCE(REV.QtyPack * REV.PCS + REV.QtyStan, 0)
WHERE rev.Status = 'Posted' AND
rev.date between $date1 and $date2;
The COALESCE() converts NULL values to 0, which is part of the third condition.

how to perform count using nested select in a select statement

So here is the issue. I'm trying to write a new fillrate report because the one built in is not good enough... I'm trying to run a single select statement to return both, a count of how many times an item was ordered for a specific month, and then also a count of how many times it was invoiced/shipped in full.
This code is obviously wrong, I also currently have it restricted to only look at AUG of 2015, but that is just to simplify results during testing.
I can't figure out how to do the 2nd count... This is what I was trying (brain stuck on old for each loop logic):
select inv_mast.item_id,
inv_mast.item_desc,
"YEAR" = year(oe_line.required_date),
"MONTH" = month(oe_line.required_date),
"ORDERS" = count(1),
"HITS" = (
select count(1)
from invoice_line
where invoice_line.order_no = oe_line.order_no
and invoice_line.oe_line_number = oe_line.line_no
and invoice_line.qty_shipped = oe_line.qty_ordered
)
from oe_line,
inv_mast,
inv_loc
where inv_mast.inv_mast_uid = oe_line.inv_mast_uid
and inv_mast.delete_flag = 'N'
and inv_mast.inv_mast_uid = inv_loc.inv_mast_uid
and inv_loc.location_id = '101'
and year(oe_line.required_date) = '2015'
and month(oe_line.required_date) = '8'
group by inv_mast.item_id,
inv_mast.item_desc,
year(oe_line.required_date),
month(oe_line.required_date)
order by inv_mast.item_id
To me it would seem like you could rewrite the query to use a left join on the invoice_line table instead. Without any proper test data I can't guarantee it is correct, but I think it should be.
Besides the left join I also changed to explicit joins and moved the aliases as I don't think MySQL supports the alias = column syntax.
select inv_mast.item_id,
inv_mast.item_desc,
year(o.required_date) as "YEAR",
month(o.required_date) as "MONTH",
count(1) as "ORDERS",
count(invoice_line.order_no) as "HITS"
from oe_line o
join inv_mast on inv_mast.inv_mast_uid = o.inv_mast_uid
join inv_loc on inv_mast.inv_mast_uid = inv_loc.inv_mast_uid
left join invoice_line on invoice_line.order_no = o.order_no
and invoice_line.oe_line_number = o.line_no
and invoice_line.qty_shipped = o.qty_ordered
where inv_mast.delete_flag = 'N'
and inv_loc.location_id = '101'
and year(o.required_date) = '2015'
and month(o.required_date) = '8'
group by inv_mast.item_id,
inv_mast.item_desc,
year(o.required_date),
month(o.required_date)
order by inv_mast.item_id;

unknown class: Fixnum Rails MySQL query - inserting variable breaks my search

I had a query which was working just fine:
#schedule = Schedule.find(params[:id])
#schedule_tasks = ScheduleTask.select("s.*, t.*, t.*, d.*, st.*").from("schedule_tasks st").
joins("left join schedules s ON s.id = st.schedule_id").
joins("left join tasks t ON t.id = st.task_id").
joins("right join days d ON d.id = st.day_id").
order("d.number, t.name").
group_by{|d| d.number}
I had to refine my search to only schedule_tasks with a specific schedule_id, so I edited the second line to:
joins("left join schedules s ON s.id = st.schedule_id AND s.id = ?", #schedule.id).
This has cause the following error:
unknown class: Fixnum
The error goes away if I take out the group_by - but I need that, and I have tried hard coding in the number instead of #schedule.id and that does not work either, a google search does not reveal a lot of details on this error.
For anyone coming here from Google, I used plain string interpolation to fix this issue. This method is vulnerable to SQL Injection, so make sure you type check your variables before using them.
In this case I would do
#schedule_id = #schedule.id
.
.
.
joins("left join schedules s ON s.id = st.schedule_id AND s.id = #{#schedule_id}")
Rather than following learning_to_swim's answer, which as noted is at risk of SQL injection, couldn't you cast your #schedule_id to a string?
#tasks = ScheduleTask.joins("left join [...] s.id = ?", #schedule.id.to_s)

Comparing dates in iif() in SQL Server

I am trying to use the following query in SQL Server
SELECT [AL].[Subscriptions].Id,
[AL].[Subscriptions].name,
[AL].[Subscriptions].description,
[AL].[Subscriptions].price,
[AL].[Subscriptions].iconFileName,
IIf(a.expiryDate > Now(), 'TRUE', 'FALSE') AS isSubsByUser
FROM [AL].[Subscriptions]
LEFT JOIN (SELECT *
FROM [AL].[UserSubscriptions]
WHERE userId = 13259) AS a
ON Subscriptions.Id = a.itemid;
but always get the error
Error in list of function arguments: '>' not recognized.
Unable to parse query text.
How do I resolve it?
Like Martin Smith said you need to use a case statement. Also it looks like you are only using a couple of fields in the derived table therefor I would suggest not using *. I put a example below.
SELECT [AL].[Subscriptions].Id,
[AL].[Subscriptions].name,
[AL].[Subscriptions].description,
[AL].[Subscriptions].price,
[AL].[Subscriptions].iconFileName,
case when a.expiryDate > GetDate() then 'TRUE' else 'FALSE' end AS isSubsByUser
FROM [AL].[Subscriptions]
LEFT JOIN (SELECT expiryDate, itemid
FROM [AL].[UserSubscriptions]
WHERE userId = 13259) AS a
ON Subscriptions.Id = a.itemid;

Linq to Sql - Use sum in the where clause

I'm trying to select orders that have either over or under 2000 products ordered in them, depending on other values. I need to select the information from the Orders table, but check this value in the OrdersProducts table, specifically the sum of OrdersProducts.ProductQty. I also need to do this using predicate builder, because of other requirements. So far, I have this, but it isn't returning the results correctly. Its using nested Lambda expressions, which I didn't know I could do but I tried it and it works, but its not returning correct results.
Dim getOrders = From d In db.Orders _
Where d.Status = OrderStatus.Approved _
Select d
' Then a for loop adding parameters via Predicatebuilder...
If over2000 = True Then
' over 2000
predicate1 = predicate1.And(Function(d) (d.OrderProducts.Sum(Function(c) c.ProductQty > 2000)))
Else
' under 2000
predicate1 = predicate1.And(Function(d) (d.OrderProducts.Sum(Function(c) c.ProductQty < 2000)))
End If
basePredicate = basePredicate.Or(predicate1)
' End For loop
getOrders = getOrders.Where(basePredicate)
I removed some code for brevity but I think that gets the point across. How can I do this?? Thanks!
Try changing this:
(d.OrderProducts.Sum(Function(c) c.ProductQty > 2000))
to this:
(d.OrderProducts.Sum(Function(c) c.ProductQty) > 2000)
I haven't built this to test it, but it appears that it was currently trying to sum the results of a boolean comparison instead of summing the quantities and then comparing.