Aggregate count and sum in SQL

Viewed 45

I have 3 SQL table

TABLE 1:

VIN model color
83498 Ford Fusion yellow
233244 Renault Car Red
2343 Renault Car Red

TABLE 2: Translation VIN to License plate

VIN License_plate
83498 ABC123
233244 EDF567
2343 YEL898

Table 3: Table showing license plate at Spots

License_plate Spot
ABC123 1
EDF567 1
YEL898 2
YEL898 4
YEL898 5
EDF567 2

How can I write a SQL query to see if a model number has been spotted at multiple spots ?

2 Answers

In SQL we can use GROUP BY to create sets of results to aggregate the values in each set, when you want to limit the Groups with an aggregate function we use HAVING to express the desired filter condition.

The first step is to construct a query that resolves the Model that was sighted at each Spot:

SELECT t3.license_plate, t1.model, t3.Spot
FROM table3 t3 
INNER JOIN table2 t2 ON t3.license_plate = t2.license_plate 
INNER JOIN table1 t1 ON t2.vin = t1.vin

It is always a good idea to inspect this raw result set first, to ensure that your joins are expressed correctly, this will result in the following:

license_plate model Spot
ABC123 Ford Fusion 1
EDF567 Renault Car 1
YEL898 Renault Car 2
YEL898 Renault Car 4
YEL898 Renault Car 5
EDF567 Renault Car 2

From that result set, we expect to find that Renault Car is spotted multiple times, we can use GROUP BY and the COUNT function to calculate the number of spot values that each model was sighted at:

SELECT t1.model, COUNT(t3.Spot) as [Spots]
FROM table3 t3 
INNER JOIN table2 t2 ON t3.license_plate = t2.license_plate 
INNER JOIN table1 t1 ON t2.vin = t1.vin
GROUP BY t1.model

This returns:

model Spots
Ford Fusion 1
Renault Car 5

Finally, we can use the HAVING clause to filter the results based on the result of the COUNT() aggregate function:
multiple can be expressed in SQL as "more than 1"

SELECT t1.model
FROM table3 t3 
INNER JOIN table2 t2 ON t3.license_plate = t2.license_plate 
INNER JOIN table1 t1 ON t2.vin = t1.vin
GROUP BY t1.model
HAVING COUNT(Spot) > 1
model
Renault Car

You can see this in action here: http://sqlfiddle.com/#!18/26ed4/2
In the fiddle the number of spots is also included in the output.

You can use aggregation -- after joining the tables together of course:

select t1.model
from table3 t3 join
     table2 t2
     on t3.license_plate = t2.license_plate join
     table1 t1
     on t2.vin = t1.vin
group by t1.model
having min(spot) <> max(spot);
Related