MS Access: Ignoring query criteria if blank - sql

I have a form in Access where I run a query based on several text boxes. I apply criteria on several of the query fields that is pulled from the text boxes but would like the query to ignore the criteria when the text box is blank.
For example, if the Machine_TextBox is blank, do not apply criteria to the Events.Machine field.
SQL code is:
SELECT Events.Machine, Events.[Event Date], Events.[Event Description],
Events.[Action Taken], Events.[Machine Clinical], Events.[Modalities Not Clinical],
Events.[Manufacturer Ticket #], Events.[TLC Ticket #], Events.FSR, Events.ID,
Events.[Event Recorded By], Events.[Action Recorded By], Events.[Downtime Validation],
Events.[Event Time]
FROM Events
WHERE (((Events.Machine)=IIf([Forms]![SearchEvent]![Machine_TextBox] Is Null,"",
[Forms]![SearchEvent]![Machine_TextBox])) AND ((Events.[Event Date]) Between
Nz([Forms]![SearchEvent]![StartDate_TextBox],#1/1/1900#) And Nz([Forms]![SearchEvent]![EndDate_TextBox],#1/1/2100#))
AND ((Events.[Event Description]) Like "*" & [Forms]![SearchEvent]![EventDetails_TextBox])
AND ((Events.[Manufacturer Ticket #])=[Forms]![SearchEvent]![Manufacturer_TextBox])
AND ((Events.[TLC Ticket #])=[Forms]![SearchEvent]![TLC_TextBox])
AND ((Events.FSR)=[Forms]![SearchEvent]![FSR_TextBox]))
OR (((Events.Machine)=IIf([Forms]![SearchEvent]![Machine_TextBox] Is Null,"",[Forms]![SearchEvent]![Machine_TextBox]))
AND ((Events.[Event Date]) Between Nz([Forms]![SearchEvent]![StartDate_TextBox],#1/1/1900#)
AND Nz([Forms]![SearchEvent]![EndDate_TextBox],#1/1/2100#))
AND ((Events.[Action Taken]) Like "*" & [Forms]![SearchEvent]![EventDetails_TextBox])
AND ((Events.[Manufacturer Ticket #])=[Forms]![SearchEvent]![Manufacturer_TextBox])
AND ((Events.[TLC Ticket #])=[Forms]![SearchEvent]![TLC_TextBox])
AND ((Events.FSR)=[Forms]![SearchEvent]![FSR_TextBox]))
ORDER BY Events.[Date and Time Stamp] DESC;
Yours sincerely,
Mark

You can try the technique described here.
For each search box, use boolean logic to either filter for its value, or ignore this AND clause if it's empty, by making the AND clause TRUE.
I'll just use two search boxes as example:
SELECT stuff
FROM Events
WHERE ((Events.Machine = [Forms]![SearchEvent]![Machine_TextBox])
OR ([Forms]![SearchEvent]![Machine_TextBox] Is Null))
AND ((Events.[Event Description] Like "*" & [Forms]![SearchEvent]![EventDetails_TextBox] & "*")
OR ([Forms]![SearchEvent]![EventDetails_TextBox] Is Null))
AND ...

Related

SQL WHERE clause searching for multiple parameters from one field

Essentially I would like the MS Access query to output all records that meet all three of the following criteria:
Expanded_Status = "Eligible but not enrolled"
Hospital = "UHN"
Comments = "transplant" or "tx" or "post-transplant"
The comments field has 3 different versions of the word "transplant" so some fields may have "tx" instead of "transplant" and some records may have "post-transplant" instead of "transplant".
The query below is outputting records that don't match all three of the criteria for some reason.
Please help me modify the query so that I can find only records with all three criteria fulfilled
SELECT [First Name], [Last Name], [Subject ID], Expanded_Status, Hospital, Comments
FROM [Barriers UHN Screen - 2017 Mailing]
WHERE Expanded_Status = "Eligible but not enrolled" AND Hospital = "UHN" AND Comments LIKE "transplant" OR Comments OR "post transplant" OR Comments = "tx";
Building on #Harun24HR 's answer:
SELECT
[First Name], [Last Name], [Subject ID], Expanded_Status, Hospital, Comments
FROM
[Barriers UHN Screen - 2017 Mailing]
WHERE
Expanded_Status = "Eligible but not enrolled" AND Hospital = "UHN" AND
(LOWER(Comments) LIKE "*transplant*" OR LOWER(Comments) LIKE "*post transplant*" OR LOWER(Comments) LIKE "*tx*");
I added two things:
Calling lower on Comments makes sure you are only comparing lower cased string - if someone has "Post Transplant" in the comments, it might not match on "post transplant"
Wildcards * on the beginning and end of the comparison string - this tells Access my comparison string can be anywhere in the comments.
Like Operator
Zuva,
Try this
SELECT
[First Name], [Last Name], [Subject ID], Expanded_Status, Hospital, Comments
FROM
[Barriers UHN Screen - 2017 Mailing]
WHERE
Expanded_Status = "Eligible but not enrolled" AND Hospital = "UHN" AND
(Comments = "transplant" OR Comments = "post transplant" OR Comments = "tx");
Enclosing the Comment section of the where clause in brackets, tells access to evaluate each separately as part of the AND clause.

Need MS Access Form Field to automatically Calculate and Allocate Costs based on given Parameters

Below is my mock database that I am using. I have four different tables: Tbl_MainDatabase, Tbl_InsuranceCoverage, Tbl_MatterDetail, and Tbl_PaymentProcessing.
What I want -
I want my form to determine the remaining Retention Limit (i.e., Retention Limit for the applicable policy - sum of invoices for the same Claim Number )
According to the mock database, the required answer should be [ $2500 - (300+700+355)] as highlighted for your convenience
What I tried
I used the help of Graphical representation through the following query:
SELECT [Claim Number], Sum([Net Invoice Amount])
FROM [PaymentProcessing]
GROUP BY [Claim Number]
This method works to show me how much I spent per claim number so far in the form of a graph. However I want to display the remaining amount.
Any Help is appreciated :)
I am one month old at using Access. But I am trying my best to learn
Thank you in advance!
SELECT
IC.[Retention Limit]-SUM([Net Invoice Amt]) AS Remaining, MD.[Claim Number], IC.[Retention Limit], IC.InsuranceID
FROM tbl_InsuranceCoverage IC
INNER JOIN tbl_MatterDetail MD ON ic.InsuranceID = MD.Policy
INNER JOIN tbl_PaymentProcessing PP ON MD.MatterDetailID=pp.MatterDetailID AND MD.[Claim Number]=pp.[Claim Number]
GROUP BY MD.[Claim Number], IC.[Retention Limit], IC.InsuranceID
See if this works. Havent tested it but seems simple. You can remove the extra columns, but this will hlep you understand joins a bit
For All the New users The above code by #Doug Coats works perfectly.
Make Sure All the Foreign Key and Primary Keys is linked in the Relationship Property. ( One of the way To do this in the Query is - Right click on the Query and select Design View --> Right click again on the grey space and Select Show all Tables Now Drag your Primary Key of the table and drop at the foreign Key on the other table --> This will create a relationship between both for the Query Purpose.
This will also Prevent Data from Duplication in the query then use a similar code as described by Doug Coats in the above comment in the SQL View
SELECT [Insurance Coverage].[Retention Unit]-Sum([Net Invoice Amount]) AS Remaining, [Matter Detail].[Claim Number], [Insurance Coverage].[Retention Unit], [Matter Detail].Policy
FROM (([Main Database] INNER JOIN [Matter Detail] ON [Main Database].[Database ID] = [Matter Detail].[Short Name]) INNER JOIN [Payment Processing] ON ([Matter Detail].[Matter Detail ID] = [Payment Processing].[Matter Detail ID]) AND ([Main Database].[Database ID] = [Payment Processing].[Short Name])) INNER JOIN [Insurance Coverage] ON [Matter Detail].Policy = [Insurance Coverage].[Insurance ID]
GROUP BY [Matter Detail].[Claim Number], [Insurance Coverage].[Retention Unit], [Matter Detail].Policy;
You can then display this query in the form - I am still evaluating best way to display this query probably in a Combo Box (Not sure if any other controls has a row source)
Thank you

Macro to Run Custom Sql Query in Access off Data in Table?

Coworker is completely Access adverse. I can't force him to update a SQL query with a to/from date and customer name. Current query is this:
SELECT [all customers]
FROM [information list]
WHERE
[date] Between [start date YYYYMMDD] and [end date YYYYMMDD]
and [all customers] = ['specific customer']
Group By [all customers] (this prevents duplicate entries or shipping a customer's order between factories counting as a separate order)
This coworker is so access adverse he wants a wysiwyg and a button to press to overwrite [start date YYYYMMDD] [end date YYYYMMDD] ['specific customer']
I can make a form just fine, but I have no idea how to populate the sql query with form answers. Having him copy and paste these three things into my perfectly good, working query is out of the question, as easy as that answer is.
How would i write a macro that can update this query with those answers replacing the three existing items (the two dates and customer ID)?
you concatenate the textbox values to create the sql query string
sql = "SELECT [all customers] FROM [information list]" _
& "WHERE [date] Between ['" & myForm.Textbox1.Text _
& "'] and ['" & myForm.Textbox2.Text _
& "'] and [all customers] = ['" & myForm.Textbox3.Text _
& "'] Group By [all customers]"
adjust the form name and the textbox names to fit your needs

Aggregating Child Records at the Parent Level in Access 2010

The link above will provide an excel sheet with some sample data from both the parent and child table with expected result from the query.
Alright this should be simple but I just can't wrap my head around this for some reason. Pretty much, I have a parent table that is linked to a child table. I want to pull up few of the fields from the child table and merge it with the parent fields. I want to create a view of sort in Access.
The parent record can have multiple child records (1 - many relationship). I want to only pull up one record from the child and merge with the parent. The parent table is called Tank and the child table is Tank_Inspections. The IF statement you see below is a conditional statement that helps in determining which Out of Compliance date I should be pulling up. The issue I'm having is that the Out of Compliance date is tied to inspection type. A Tank can have multiple different inspection types. They query below merges the inspection out of compliance date with few of the tank (parent) fields. However, I want to be able to add more of the child fields (in addition to the inspection out of compliance date) but I can't do that without adding those fields to the group by clause as well. If I do that, then I won't get the right amount of records.
As you can see, the left join is getting all of the records from the parent table which is what I need. If I add any more child table fields to the query, I'll also need to add them to the group by clause and then I'll get more records than what's in the parent table. Essentially, I need to only get the records from the parent table, and then merge child fields in. I may be missing few sub queries... Any suggestions? This is what I have so far and I'm getting the right amount of records. But adding more child fields to the select statement will add more rows than i need...
SELECT parent.tankid, IIf(Min(Nz(child.[tank inspection out of compliance date], #1/1/1901#)) <> #1/1/1901#, Min(child.[tank inspection out of compliance date]), IIf(Min(Nz(child.[tank inspection out of compliance date],#1/1/1901#)) = #1/1/1901# And Max(child.[tank inspection out of compliance date])>Date(), NULL, Min(child.[tank inspection out of compliance date]))) AS [Tank Inspection Out of Compliance Date]
FROM
tank as parent
LEFT JOIN
(
SELECT * FROM tank_inspections WHERE tank_inspections.[actual inspection date] is null
) AS child ON parent.tankid = child.tankid GROUP BY parent.tankid
I was able to modify Parfait suggested query below to come up with this:
SELECT
Site.[Manager] AS PM, Site.[DLA Site Code], Tank.[Name] AS [Name], Tank.[Local Name],
Tank.RPID, Tank.[Fac Num], Tank.[Status], Tank.[Type], Tank.[Capacity], Tank.[Current Prod], IIf(main.[Inspection Out of Compliance Date]<Date() AND NOT IsNull(main.[Inspection Out of Compliance Date]), 'Out of Compliance',
IIf(isnull(main.[Inspection Out of Compliance Date]) OR main.[Inspection Out of Compliance Date]=#1/1/1901#,'Unknown Compliance Status')) AS [Compliance Status], Tank.[EA], Site.Serv, Site.[Name], Tank.Comments, main.[Type], main.[Inspection Out of Compliance Date], main.[Planned Prog Date], main.[Prog Date], main.[Prog Year], main.[Planned Inspection Date], IIf(main.[Inspection Out of Compliance Date]<DateAdd('m',12,Date()) And main.[Prog Date] Is Null,'Action Required') AS [Inspection Planning Action Required], main.[Inspection Comments], tank.TankID, main.inspectionid
FROM
Site INNER JOIN
(
(
(
SELECT ti.tankid, ti.inspectionid, ti.[Type], ti.[Inspection Out of Compliance Date], ti.[Planned Prog Date], ti.[Prog Date], ti.[Prog Year], ti.[Planned Inspection Date], ti.[Inspection Comments] FROM Tank_Inspections AS ti) AS main INNER JOIN Tank ON main.TankID = Tank.TankID) INNER JOIN
(
SELECT [TankID], dlookup("InspectionID", "Tank_Inspections", "[Tank Inspection Out of Compliance Date] " & IIf(Min(Nz([inspection out of compliance date], #1/1/1901#)) <> #1/1/1901#, "= #" & Min([inspection out of compliance date]) & "#", IIf(Min(Nz([inspection out of compliance date],#1/1/1901#)) = #1/1/1901# And Max([inspection out of compliance date])>Date(), "IS NULL", IIF(Min(Nz([inspection out of compliance date],#1/1/1901#)) = #1/1/1901# And Max([inspection out of compliance date])<Date(), "= #" & Min([inspection out of compliance date]) & "#", "IS NULL"))) & " AND TankID = " & TankID & " AND [Actual Inspection Date] is null") AS MinInspectionID FROM Tank_Inspections WHERE [Actual Inspection Date] is null GROUP BY [TankID]
)AS DT ON
(
main.InspectionID = Cint(DT.MinInspectionID)
) AND (main.TankID = DT.TankID)
) ON Site.SiteID = Tank.SiteID
WHERE IIf(main.[Inspection Out of Compliance Date]<Date() And NOT IsNull(main.[Inspection Out of Compliance Date]),'Out of Compliance',IIf(isnull(main.[Inspection Out of Compliance Date]) OR main.[Inspection Out of Compliance Date]=#1/1/1901#,'Unknown Compliance Status'));
I'm close with this query, however, I'm missing a few records. The parent records don't have some of the child records. For example, some of the tank records don't have any inspection records so it's not being pulled. I need to do a left join but can't seem to figure it out with this query. Everything I try doesn't seem to work. Suggestion?
Consider the following query that uses a derived table and joins the unit level parent (Tank) to aggregated child (TankInspections). You can save the derived table as a separate stored query and just replace entire select statement and alias (DT) with query name. I include more aggregates than needed for you to check calculated columns:
SELECT Tanks.*, main.*, DT.MaxInspectionID, DT.MaxInspectionOrComplianceDate
FROM
(TankInspections main
INNER JOIN Tanks ON Tanks.TankID = main.TankID)
INNER JOIN
(
SELECT [TankID],
Max(InspectionID) As MaxInspectionID,
Min([Planned Inspection Date]) As MinInspection,
Max([Planned Inspection Date]) As MaxInspection,
Min([Inspection Out of Compliance Date]) As MinCompliance,
Max([Inspection Out of Compliance Date]) As MaxCompliance,
Max(IIF(([Planned Inspection Date]) Is Null,
IIF(ISNULL([Inspection Out of Compliance Date]),
NULL,
[Inspection Out of Compliance Date]),
[Planned Inspection Date])) As MaxInspectionOrComplianceDate
FROM TankInspections
GROUP BY [TankID]
) As DT
ON main.TankID = DT.TankID
AND main.InspectionID = DT.MaxInspectionID;

SQL query ordering wrong, not sure why

SELECT a.[Evaluation Number], a.[CSO Name], a.service
, a.[Date of call], a.[Name of Monitor]
, a.[Date Sheet Completed]
FROM [KD call monitoring] AS a
WHERE a.[Evaluation Number]
IN (SELECT TOP 1 [Evaluation Number]
FROM [KD call monitoring] b
WHERE b.[CSO Name] = a.[CSO Name]
AND b.[Date of Call] =
(SELECT MAX([date of call])
FROM [KD call monitoring]
WHERE [cso name] = a.[CSO Name])
ORDER BY [Evaluation Number]);
this is the code i have on my call evaluation database at work, it is ordering the entries so i know which employee has not had their calls monitored for a while. however it orders fine from 31st jan up until the end of febuary (about halfway down the list) then just places random peoples entries before settling down and giving me the most recent person and entry that has been evaluated.
this list only needs to show one entry per person - the latest one.
im not sure if its messing up because of the leap year or something but i have no idea how to fix it!
im using ACCESS XP. and i would attach an image however im a new user so not allowed!
You don't seem to have an ORDER BY on your outer-most query so the final resultset will not be ordered.