By Ken Bluttman, Wayne S. Freeze
Book Price: $49.99 USD
£35.50 GBP
PDF Price: $39.99
Cover | Table of Contents | Colophon
AND operator returns true when all conditions are met; the OR operator returns true as long as one condition is met. In terms of how this applies to SQL construction, OR is used to set criteria for which one condition must be met, while AND is used to set criteria for which all the conditions must be met. Some examples are presented in .|
SQL statement
|
Description
|
|---|---|
SELECT DISTINCT State, City, Count(LastName) AS Customers FROM tblCustomers GROUP BY State, City HAVING State="NY" AND City="Yonkers" |
This gives a count of customers located in Yonkers, NY. Only customer records in which both the state is New York and the city is Yonkers are counted.
|
SELECT DISTINCT State, City, Count(LastName) AS Customers FROM tblCustomers GROUP BY State, City HAVING State="NY"AND City="Yonkers" OR City="Albany" |
This gives a count of customer records for which the state is New York and the city is either Yonkers or Albany.
This produces an unintended result. The
OR statement does not properly apply to both Yonkers and Albany. Any Yonkers customers must be in New York, but the way this SQL statement is constructed, Albany customers do not have to be in New York. Consequently, as shows, customers in Albany, GA will also be returned. |
SELECT DISTINCT State, City, Count(LastName) AS Customers FROM tblCustomers GROUP BY State, City HAVING State="NY" AND (City="Yonkers" OR City="Albany") |
OR operators in the query grid makes for an unmanageable experience. If too many values and ORs are placed in a grid column, the column may expand to be bigger than the viewable area.IN operator. IN is used in conjunction with a list of values from which any value can be returned. This essentially means that the IN operator works in the same fashion as the OR operator. It is not required that all conditions be met; meeting one of the conditions suffices.SELECT Students.Student, Student_Grades.Course, Student_Grades.Instructor FROM Students INNER JOIN Student_Grades ON Students.StudentID = Student_Grades.StudentID WHERE (((Student_Grades.Course)="Beginner Access")) OR (((Student_Grades.Course)="Beginner Excel")) OR (((Student_Grades.Course)="Advanced Access")) OR (((Student_Grades.Course)="Advanced Excel"));
IN provides a more streamlined SQL statement. Notice how the WHERE section has shrunk: SELECT Students.Student, Student_Grades.Course,
Student_Grades.Instructor
FROM Students INNER JOIN Student_Grades ON
Students.StudentID = Student_Grades.StudentID
WHERE Student_Grades.Course In
("Beginner Access","Beginner Excel",
"Advanced Access","Advanced Excel");IN operator provides a syntax convenience. It makes it easier to eyeball a set of criteria values to which OR logic is applied. shows an example of using IN to return records where the instructor is either Brown or Maxwell.
IN in two fields.
NOT operator provides the twist to make the records excluded instead of included.NOT operator is placed in front of the subquery to reverse the logic. If NOT were left out, the query would return records that match in both tables. When NOT is applied, only those records from the Clients table that do not have matching records in the OnHold table are returned. Here is the SQL statement:SELECT Clients.ClientID, Clients.Client, Clients.OrderDate, Clients.OrderAmount FROM Clients WHERE (((Clients.ClientID) NOT In (Select ClientID from OnHold)));
NOT is a logic operator that reverses a Boolean state, so NOT true equals false, and NOT false equals true. When a query calls for matching criteria, preceding the criteria construct with NOT flips this around and calls for records that specifically do not match the criteria.
SELECT Name_City_Age.ID, Name_City_Age.FirstName, Name_City_Age.LastName, Name_City_Age.City, Name_City_Age.Age FROM Name_City_Age WHERE (((Name_City_Age.Age)=[Enter an age]));
WHERE clause the phrase "Enter an age" appears enclosed in brackets.TOP predicate is just what is called for here. It lets you specify how many records to return, either as an exact number or as a percentage of the total number of records in the underlying table or query.SELECT SampleNum, Identifier, Fact1, Fact2, Fact3, Fact4, Fact5, Fact6, Fact7, Fact8 FROM ConsumerTrendData;
TOP predicate, as follows:SELECT TOP 40 SampleNum, Identifier, Fact1, Fact2, Fact3, Fact4, Fact5, Fact6, Fact7, Fact8 FROM ConsumerTrendData;
TOP comes directly after the SELECT keyword, and is followed by the number of records to return. Instead of reducing the number of returned records based on criteria, TOP reduces the number of returned records without any bias.TOP by going into the query properties. To do this, use the View → Properties menu option while designing the query. The properties sheet that opens may display the properties for a field. If this is the case, click on the top pane of the query designer (above the grid)but not on any tables—in other words, click on the empty area. This will ensure that the properties sheet displays the query properties (see ).
Distinct and DistinctRow:Distinct
Distinct will exclude duplicates when the duplication occurs within just the selected fields, regardless of whether the complete set of record fields would prove the records to be unique.DistinctRow
DistinctRow is used to manage duplicates in a query that joins tables. Assuming unique records in the parent table, DistinctRow lets you avoid having duplicates returned from the child table.
DISTINCTRnd function. shows a table with three fields. To return the records in a random order, pass the name of one of the fields as the argument to the Rnd function in the ORDER BY clause of the SQL statement.SELECT Samples.Location, Samples.Temperature, Samples.Date FROM Samples ORDER BY Rnd(Samples.Temperature);
Rnd function on one field while performing an ascending or descending sort on another field provides an interesting, sometimes useful result. For example, this SQL statement performs sorts on two fields (one ascending and one random):SELECT Samples.Location, Samples.Temperature, Samples.Date FROM Samples ORDER BY Samples.Location, Rnd(Samples.Temperature);
AVG aggregate function calculates the average value of a field across the records included in a query. While that is a straightforward operation, comparing the value in each record to the average presents a challenge. One way to do this is to use a subquery. A subquery is literally a query within a query, typically located within the WHERE section of the main query.
AVG aggregate function (see )is needed, but it is not applied in the typical way in the query grid. unmatched_ shows how the query is entered into the query grid. Select View → Totals while designing the query to display the Total row in the grid. Then, create an additional column in the grid based on the SeasonScore field. Don't select AVG in the Total row; instead, select Where from the drop-down list, and enter the subquery in the Criteria row.
AVG function appears in the subquery itself, which has the following syntax:Select AVG(SeasonScore) From SeasonScores
SELECT Team, SeasonScore FROM SeasonScores WHERE (((SeasonScore)> (Select AVG(SeasonScore) From SeasonScores))) GROUP BY Team, SeasonScore ORDER BY Team;
WHERE section of the outer query. An alternative is to have the subquery act as one of the fields in the outer query's SELECT section. shows two tables and a query. On the left is the SeasonScores table presented earlier. On the right is a related child table that lists game dates and locations for each team in the first table. The query, whose result is shown underneath the tables, has returned the date of the last game played by each team.Union SQL clauses between the Select statements that query the tables.SELECT * From SeasonScores_Putnam Union SELECT * From SeasonScores_Rockland Union SELECT * From SeasonScores_Westchester;
IIf function is incorporated into our derived Message field. Now, the message about the Spring Special will appear only in records that have a balance of 100 or less.
SELECT [FirstName] & " " & [LastName] AS Client, IIf([Balance]<=100,"Don't Miss Our Spring Special!","") AS MessageFROM tblClients;
FROM keyword, where the table name is entered. Follow the table name with an alias of your choosing (make sure it is not a reserved word, an existing field name, etc.). Then, use the alias instead of the table name in the other areas of the SQL statement. Let's look at an example.SELECT tblCustomers.CustomerCompanyName, tblCustomers.CustomerFirstName, tblCustomers.CustomerLastName, tblCustomers.CustomerAddr1, tblCustomers.CustomerAddr2, tblCustomers.CustomerCity, tblCustomers.CustomerState, tblCustomers.CustomerZip, tblCustomers.CustomerHomePhone, tblCustomers.CustomerWorkPhone FROM tblCustomers;
FROM section, and all references to the table name in the rest of the query just use the alias:SELECT C.CustomerCompanyName, C.CustomerFirstName, C.CustomerLastName, C.CustomerAddr1, C.CustomerAddr2, C.CustomerCity, C.CustomerState, C.CustomerZip, C.CustomerHomePhone, C.CustomerWorkPhone FROM tblCustomers C;
SELECT tblCustomers.CustomerCompanyName, tblCustomers.CustomerFirstName, tblCustomers.CustomerLastName, tblCustomers.CustomerAddr1, tblCustomers.CustomerAddr2, tblCustomers.CustomerCity, tblCustomers.CustomerState, tblCustomers.CustomerZip, tblInvoices.InvoiceNumber, tblInvoices.InvoiceDate, tblInvoices.Status, tblInvoices.Hours, tblInvoices.Rate, tblInvoicePayments.PaymentAmount, tblInvoicePayments.PaymentDate, tblInvoicePayments.PaymentType FROM (tblCustomers INNER JOIN tblInvoices ON tblCustomers.CustomerID = tblInvoices.CustomerID) INNER JOIN tblInvoicePayments ON tblInvoices.InvoiceID = tblInvoicePayments.InvoiceID;
SELECT Teams.Team, Games.Date, Games.Location FROM Games LEFT JOIN Teams ON Games.TeamID=Teams.TeamID UNION SELECT Teams.Team, Games.Date, Games.Location FROM Games RIGHT JOIN Teams ON Games.TeamID = Teams.TeamID ORDER BY Team, Date;
Sum and Avg (for calculating the average). You can easily incorporate these into your query's design right within the query grid.Sum function to the Amount field. shows the design of the query, with the Sum and Avg (for calculating the average). You can easily incorporate these into your query's design right within the query grid.Sum function to the Amount field. shows the design of the query, with the Sum function selected from the drop-down list in the Total row for the Amount field.
Group By clause is a keystone. This SQL clause provides a grouping segregation, which then allows aggregation summaries to be applied per grouping. In this example, the Group By clause is applied to the State field. Then, the Count aggregate function is used to return the count of customers per group (i.e., per state).Count function is selected from the drop-down list in the Total row.
Group By clause can be applied to more than one field. In such a case, in sequence, each field that uses Group By further defines the narrowness of the count at the end.SELECT tblCustomers.State, tblCustomers.City, Count(tblCustomers.CustomerID) AS Customers FROM tblCustomers GROUP BY tblCustomers.State, tblCustomers.City;
Select statement. Last Service Date: IIf([PetID]<300,
DLookUp("Max(DateOfService)",
"tblServiceDates","[Pet_ID]=" & [PetID]),
DLookUp("Max(DateOfService)",
"tblServiceDates_New",
"[Pet_ID]=" & [PetID]))
IIf, DLookup, and Max) to find the last service date for each pet from the respective service date tables. SELECT tblPets.PetID, tblClients.ClientLastName,
tblPets.PetType, IIf([PetID]<300,
DLookUp("Max(DateOfService)",
"tblServiceDates","[Pet_ID]=" & [PetID]),
DLookUp("Max(DateOfService)","tblServiceDates_New",
"[Pet_ID]=" & [PetID])) AS [Last Service Date]
FROM tblClients INNER JOIN tblPets ON
tblClients.ClientID = tblPets.ClientID;bill_amount function:Function bill_amount(the_date As Date, the_hours As Integer, _ the_client As String, WorkType As String) As Single bill_amount = 0 'in case of unexpected input Select Case WorkType
Case "Training" bill_amount = the_hours * 80 Case "Development" bill_amount = the_hours * 120 Case "Maintenance" 'Parker gets reduced rate regardless of day of week 'Other clients have separate weekday and weekend rates If the_client <> "Parker" Then If Weekday(the_date) = 1 Or Weekday(the_date = 7) Then bill_amount = the_hours * 95 Else bill_amount = the_hours * 75 End If Else bill_amount = the_hours * 60 End If End Select End Function
Function validate_transaction(transaction_record As String, _ match_string As String) As String validate_transaction = "Invalid Record" Dim regexp As regexp Set regexp = New regexp With regexp .Global = True .IgnoreCase = True .Pattern = match_string If .Test(transaction_record) = True Then validate_transaction = "Valid Record" End If End With Set regexp = Nothing End Function
SELECT Teams1.Team, Locations.Location FROM Teams1, Locations;