SQL oddity when using 2 tables in a query
A colleague was creating a query for two tables he has set up - UK Time and Egypt Time. The SQL for his query was as so:
SELECT Sum([UK Time].[Hours Booked]), [UK Time].[First Name], [UK Time].[Last Name], [UK Time].[Month]
FROM [UK Time], [Egypt Time]
GROUP BY [UK Time].[First Name], [UK Time].[Last Name], [UK Time].[Month]
HAVING (([UK Time].[First Name])="Geoff"), ([UK 开发者_Go百科Time].[Month])="September 2009"));
UK Time had 18 results that matched both 'Geoff' and 'September 2009', and Egypt Time had a total of 6022 entries (UK Time had a similar total number).
When running this query, it would return the 18 results, but duplicate them 6022 times each, giving a total of 108396 entries in the query. When Egypt Time was removed from the query it only showed the 18 results.
My colleague has simply created two queries now, one per table, but I was hoping somebody on here would be able to explain this behavior.
To expand on Kevin's answer:
A CARTESIAN
or FULL OUTER JOIN
basically gives a product of the tables, with a row in the result set for every row in the left table matched up with every row in the right table.
This has it's uses but they are rare.
You want to do something like
...
FROM LeftTable
INNER JOIN RightTable ON LeftTable.Key = RightTable.Key
WHERE ...
This will give you only records that match up between the two tables.
Well it would do, you have not told it how to join the two tables together so it does a Cartesian join which joins every row with every other row!
Google Inner Join to see some examples on how to do this
You didn't mention what results you are trying to achieve, but I believe you need to use UNION
:
SELECT Sum([UK Time].[Hours Booked]), [UK Time].[First Name], [UK Time].[Last Name], [UK Time].[Month]
FROM [UK Time]
GROUP BY [UK Time].[First Name], [UK Time].[Last Name], [UK Time].[Month]
HAVING (([UK Time].[First Name])="Geoff"), ([UK Time].[Month])="September 2009"))
UNION
SELECT Sum([Egypt Time].[Hours Booked]), [Egypt Time].[First Name], [Egypt Time].[Last Name], [Egypt Time].[Month]
FROM [Egypt Time]
GROUP BY [Egypt Time].[First Name], [Egypt Time].[Last Name], [Egypt Time].[Month]
HAVING (([Egypt Time].[First Name])="Geoff"), ([Egypt Time].[Month])="September 2009"));
;
Currently you are getting Cartesian product as was explained by Kevin Ross and JNK:
SELECT * FROM tablea, tableb
always return (#rows in tablea times #rows in tableb)
精彩评论