Assuming you're joining on columns with no duplicates, which is a very common case:

An inner join of A and B gives the result of A intersect B, i.e. the inner part of a Venn diagram intersection.

An outer join of A and B gives the results of A union B, i.e. the outer parts of a Venn diagram union.

**Examples**

Suppose you have two tables, with a single column each, and data as follows:

```
A B
- -
1 3
2 4
3 5
4 6
```

Note that (1,2) are unique to A, (3,4) are common, and (5,6) are unique to B.

**Inner join**

An inner join using either of the equivalent queries gives the intersection of the two tables, i.e. the two rows they have in common.

```
select * from a INNER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a = b.b;
a | b
--+--
3 | 3
4 | 4
```

**Left outer join**

A left outer join will give all rows in A, plus any common rows in B.

```
select * from a LEFT OUTER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a = b.b(+);
a | b
--+-----
1 | null
2 | null
3 | 3
4 | 4
```

**Right outer join**

A right outer join will give all rows in B, plus any common rows in A.

```
select * from a RIGHT OUTER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a(+) = b.b;
a | b
-----+----
3 | 3
4 | 4
null | 5
null | 6
```

**Full outer join**

A full outer join will give you the union of A and B, i.e. all the rows in A and all the rows in B. If something in A doesn't have a corresponding datum in B, then the B portion is null, and vice versa.

```
select * from a FULL OUTER JOIN b on a.a = b.b;
a | b
-----+-----
1 | null
2 | null
3 | 3
4 | 4
null | 6
null | 5
```

`UNION`

removes duplicate records (where all columns in the results are the same), `UNION ALL`

does not.

There is a performance hit when using `UNION`

instead of `UNION ALL`

, since the database server must do additional work to remove the duplicate rows, but usually you do not want the duplicates (especially when developing reports).

To identify duplicates, records must be comparable types as well as compatible types. This will depend on the SQL system. For example the system may truncate all long text fields to make short text fields for comparison (MS Jet), or may refuse to compare binary fields (ORACLE)

### UNION Example:

```
SELECT 'foo' AS bar UNION SELECT 'foo' AS bar
```

**Result:**

```
+-----+
| bar |
+-----+
| foo |
+-----+
1 row in set (0.00 sec)
```

### UNION ALL example:

```
SELECT 'foo' AS bar UNION ALL SELECT 'foo' AS bar
```

**Result:**

```
+-----+
| bar |
+-----+
| foo |
| foo |
+-----+
2 rows in set (0.00 sec)
```

## Best Solution

If you are looking for a one-size-fits-all, I'd suggest

`DECIMAL(19, 4)`

is a popular choice (a quick Google bears this out). I think this originates from the old VBA/Access/Jet Currency data type, being the first fixed point decimal type in the language;`Decimal`

only came in 'version 1.0' style (i.e. not fully implemented) in VB6/VBA6/Jet 4.0.The rule of thumb for

storageof fixed point decimal values is to store at least one more decimal place than you actually require to allow for rounding. One of the reasons for mapping the old`Currency`

type in the front end to`DECIMAL(19, 4)`

type in the back end was that`Currency`

exhibited bankers' rounding by nature, whereas`DECIMAL(p, s)`

rounded by truncation.An extra decimal place in storage for

`DECIMAL`

allows a custom rounding algorithm to be implemented rather than taking the vendor's default (and bankers' rounding is alarming, to say the least, for a designer expecting all values ending in .5 to round away from zero).Yes,

`DECIMAL(24, 8)`

sounds like overkill to me. Most currencies are quoted to four or five decimal places. I know of situations where a decimal scale of 8 (or more)isrequired but this is where a 'normal' monetary amount (say four decimal places) has been pro rata'd, implying the decimal precision should be reduced accordingly (also consider a floating point type in such circumstances). And no one has that much money nowadays to require a decimal precision of 24 :)However, rather than a one-size-fits-all approach, some research may be in order. Ask your designer or domain expert about accounting rules which may be applicable: GAAP, EU, etc. I vaguely recall some EU intra-state transfers with explicit rules for rounding to five decimal places, therefore using

`DECIMAL(p, 6)`

for storage. Accountants generally seem to favour four decimal places.PS Avoid SQL Server's

`MONEY`

data type because it has serious issues with accuracy when rounding, among other considerations such as portability etc. See Aaron Bertrand's blog.Microsoft and language designers chose banker's rounding because hardware designers chose it [citation?]. It is enshrined in the Institute of Electrical and Electronics Engineers (IEEE) standards, for example. And hardware designers chose it because mathematicians prefer it. See Wikipedia; to paraphrase: The 1906 edition of Probability and Theory of Errors called this 'the computer's rule' ("computers" meaning humans who perform computations).