Tuesday, August 11, 2009

What is a JOIN: Part 2 (Inner Join)

Equi-Join (Inner Join)

This is part 2 of a multi-part series on the SQL Join. For an introduction to the whole topic, take a look at:
What Is A Join: Part 1.

This time I'm going to talk about the Equi-Join, also called an Inner Join. An equi-join combines records from two tables which have common values in both tables and displays only those with matching records. Since an equi-join is the most common type of join, it is often simply referred to as a Join.

Consider the following Order and OrderDetail table

Orders

OrderID

OrderNumber

1

111

2

222

3

333

4

444


OrderDetails

OrderDetailID

OrderID

Quantity

1

1

1

2

2

2

5

3

3

6

1

2

7

1

1

8

3

2

9

3

1

Joining them on the OrderID field results in:

Single Join Query

OrderNumber

OrderID

Quantity

111

1

1

111

1

2

111

1

1

222

2

2

333

3

3

333

3

2

333

3

1


Notice that although the Orders table has a record for Order Number 444, it does not display in Single Join Query. That's because there are no matching records in OrderDetails. An equi-join shows only those records with matching values in both tables.

The SQL for this query is:

SELECT Orders.OrderNumber, OrderDetails.OrderID, OrderDetails.Quantity
FROM Orders INNER JOIN OrderDetails
ON Orders.OrderID = OrderDetails.OrderID;

In the Query Builder, it looks like this:


Notice the 1 and infinity symbol (∞) on the Join line. These indicate that a Relationship exists between these tables and that the OrderID is a Primary Key for the table on the "One-side". This is important, because if you want a query with a join of two tables to be updateable, the field or fields on the "one-side" of the join must either be a Primary Key or a Unique Index. I'll talk more about the updateability of queries in a later post.

Multiple Joins

A query is not limited to a single join. Each join is between just two tables, but the FROM clause of the query can have many joins. For instance, I can add the Products table

Products

ProductID

ProductName

Cost

Price

1

hammer

$1.00

$2.00

2

nail - 10p

$0.01

$0.02

3

saw

$5.00

$10.00

4

wrench

$6.00

$7.00

5

nail - 8p

$0.01

$0.02

6

drill

$20.00

$40.00

7

screw - 1x4

$0.02

$0.04

8

hammer

$4.00

$5.00

to the above query to get the product and price for the order.

Something like this:

MultipleJoin

OrderNumber

OrderID

Quantity

ProductName

Price

111

1

1

hammer

$2.00

222

2

2

nail - 10p

$0.02

333

3

3

saw

$10.00

111

1

2

wrench

$7.00

111

1

1

saw

$10.00

333

3

2

hammer

$2.00

333

3

1

saw

$10.00

In the Query Builder, it looks like this:


The SQL is:

SELECT Orders.OrderNumber, OrderDetails.OrderID, OrderDetails.Quantity, Products.ProductName, Products.Price
FROM Products INNER JOIN
(Orders
INNER JOIN OrderDetails
ON Orders.OrderID = OrderDetails.OrderID)
ON Products.ProductID = OrderDetails.ProductID;

Next time, I'll discuss the least common type of join, the Cartesian or Cross Join.


.

Monday, August 10, 2009

What is a Join: Part 1 (Introduction)

What is a Join: Part 1

Introduction

This is the beginning of a multi-part series devoted to Joins in Microsoft Access.

A Join connects the records of two tables based on common information in the records. In What Is Normalization: Part II, I discussed how to organize data into smaller tables to reduce redundancy. In What is Normalization: Part III, I discussed relationships and their role in defining how tables should be put back together so all of the data is retained. The Join is a SQL (Structured Query Language) implementation of a relationship. In other words, if normalization splits tables apart, the Join is how you put them back together.

In Select Queries: Part I, I talked briefly about the SQL FROM clause, where Joins are created. The general SQL syntax for the most common type of Join (Equi-Join) is:

FROM Table1 JOIN Table2 ON Table1.JoinField = Table2.JoinField

Where JoinField is a field in each table which holds the same data. So, if I had Order and OrderDetail tables, they would both have to have an OrderID field in common to relate the records in the two tables. The FROM clause for this join would be:

FROM Order JOIN OrderDetails ON Order.OrderID = OrderDetails.OrderID

Although the Equi-Join (also known as an Inner Join) is the most common, there are many different types of joins:

  1. Equi-Join (Inner Join)
  2. Cartesian Join (Cross Join)
  3. Equi-Joins in the Where Clause
  4. Outer Join (Left Join or Right Join)
    1. Unmatched Query
    2. Full Outer Join
  5. Self-Join
  6. Theta Join

In subsequent posts, I'll be discussing each of these in turn. Next up, the Equi-Join.

.

Friday, July 31, 2009

New Sample: Report_PseudoGraphs

Report_PseudoGraphs

by A.D. Tejpal

Explanatory Notes This sample db demonstrates simulated graphs on access reports, using a single text box for a given series. The following situations are covered:
  1. Monthly salary as per scales notified from time to time. For a given month and year, the most recent scale notification upto that month year becomes applicable. Whenever there is a change in salary from one month to the next, different back color is assigned so as to facilitate visual appreciation.
  2. Room bookings.
  3. Score sheets for star war games depicting the initial count of units for engine impulse, engine warp-1, engine warp-2 and superstructure. Depending upon field values in source table, series of numbered boxes are depicted.

Note: (a) Simulation of graph using a single text box is implemented by suitable manipulation of report's MoveLayout property. (b) In form F_Salary, the technique for programmatically positioning specific block of records appropriately in the display window of subform control showing notification of salary scales, is also demonstrated. (c) In order to keep sample data for salary scales current with respect to the present year, update query named Q_SalaryMaster_UpDt is executed via load event of form F_SwitchBoard. While undertaking practical adaptation of this sample db, this statement should be disabled.

You can find the sample here: http://www.rogersaccesslibrary.com/forum/forum_posts.asp?TID=509.

.

Tuesday, July 28, 2009

A Business Case for Micrsoft Access

I read the following article some years ago and just recently ran into it again. It details how Access can be used as a part of an organization's over-all business strategy.

Database Evolution: Microsoft Access within an Organization's Database Strategy
by Luke Chung, President of FMS, Inc.

Here's a part:

Abstract

There has been a lot of confusion over the role of Microsoft Access within an organization. Sitting between the power of Excel and client server databases, Access extends from simple end-user tasks to mission critical operations. This paper hopes to cover the issues surrounding Access:

  • Why it's become problematic in large organizations including the Sarbanes-Oxley Act (SOX)
  • Where it's appropriate to be used, and
  • Where it's not

It also focuses on the overall principle that most Access applications that become mission critical did not start out that way, but evolved into that role.

Software applications share many similarities with biology and Darwinian forces. Some applications evolve and survive, while others go extinct. Anticipating, rather than fighting, the inevitable process of database evolution and natural selection is the key to using Access effectively within an organization.

Read the rest of it here: http://www.fmsinc.com/MicrosoftAccess/Strategy/index.asp.

It's well worth it.

.

Thursday, July 2, 2009

New Sample: Form_CustomSeriesByDefaultProperty

Form_CustomSeriesByDefaultProperty

By A.D. Tejpal

This sample db demonstrates a novel approach involving generation of alphanumeric sequence as per specified prefix, via a common function embedded as default value property of the bound control carrying such values.

As the data entry progresses, the default value keeps incrementing as required, without having to undertake any special manipulation via form's current event. Moreover, it is not necessary to use even other form events like Dirty / Before or After Insert / Before or After Update etc.

The prefix is selected via combo box on the main form. Whenever, a new prefix is selected, the newly displayed default value on the subform gets set 1 higher than the existing highest in alpha-numeric sequence pertaining to the selected prefix. If there is no existing entry with the given prefix, the default value gets set to prefix followed by 000001.

Type of prefix can be selected via the option group as follows:
(a) Prefix by combo box selection.
(b) Prefix as per current year (yyyy)
(c) Prefix as per current year month (yyyymm)

You can find it here: http://www.rogersaccesslibrary.com/forum/forum_posts.asp?TID=471

.

Monday, June 22, 2009

New Sample: Query_SplitToMultiRowsReMergeSorted

Query_SplitToMultiRowsReMergeSorted

by AD Tejpal

Explanatory Notes

This sample db demonstrates splitting of comma (,) or star (*) separated string elements into multiple rows followed by re-merging of these elements duly sorted, back into strings. It is a virtually codeless solution, but for use of two wrapper functions related to built in Split() function.

For splitting the strings into multiple rows, a single field table (T_Ref) populated with numbers 0 to 10 is used in Cartesian join with the table holding source data. The sorted output is appended to table T_Jobs_Split, which in turn is used to generate the crosstab query followed by final select query, re-merging the sorted elements back into strings.

Note:
(a) If the maximum number of elements in one string is likely to exceed 10, additional numbers can be added to table T_Ref. At the same time, pivot clause of crosstab query and calculated field of final select query (based upon crosstab query) will need o be expanded to accommodate additional columns.

(b) Use of number reference table (as compared to master job table) in Cartesian join with source table for generating multiple rows has the advantage that it eliminates the risk of inconsistent results arising out of partial match using Like operator. Moreover, it does away with the need of preparing such a table and keeping it up-to-date, apart from ensuring that there is no inadvertent discrepancy in its contents.

Version: Access 2000 file format.
Reference: DAO 3.6

You can find the sample here: http://www.rogersaccesslibrary.com/forum/forum_posts.asp?TID=459
.