Всякий раз, когда в каждой из двух таблиц dbo.salesforce
и dbo.harvest
имеется более одного совпадения для каждого projectcode
, возникает мини- декартово произведение .Вот простая иллюстрация.Предположим, есть таблицы A
и B
, например:
Теперь, если мы выполнили это объединение:
SELECT * FROM A JOIN B ON A.AID = B.AID
результат будет:
AID AVALUE BID BVALUE AID
--- ------- --- ------- ---
1 ValueA1 1 ValueB1 1
1 ValueA1 2 ValueB2 1
2 ValueA2 3 ValueB3 2
Введите таблицу C
:
CID CVALUE AID
--- ------- ---
1 ValueC1 1
2 ValueC2 1
3 ValueC3 1
И соединение теперь таково:
SELECT * FROM A JOIN B ON A.AID = B.AID JOIN C ON A.AID = C.AID
Каким будет результат?Здесь:
AID AVALUE BID BVALUE AID CID CVALUE AID
--- ------- --- ------- --- --- ------- ---
1 ValueA1 1 ValueB1 1 1 ValueC1 1
1 ValueA1 1 ValueB1 1 2 ValueC2 1
1 ValueA1 1 ValueB1 1 3 ValueC3 1
1 ValueA1 2 ValueB2 1 1 ValueC3 1
1 ValueA1 2 ValueB2 1 2 ValueC3 1
1 ValueA1 2 ValueB2 1 3 ValueC3 1
Как видите, каждое совпадение с B
повторяется три раза, сколько совпадений получило C
.И, аналогично, каждое совпадение из C
повторяется дважды, потому что именно столько совпадений есть в B
.Самым «счастливым», конечно же, является строка из A
, потому что она повторяется 2 × 3 = 6 раз.Это декартово соединение для вас.И это именно то, что происходит и в вашем случае.
Не уверен, считается ли это типичным, но в таких случаях я часто группирую каждую таблицу отдельно по объединяющим выражениям, а затем объединяю результирующие наборы.Ваш запрос будет выглядеть так:
SELECT
p.projectcode,
p.client,
p.project,
p.budget,
p.budget * 80 AS value,
h.hourslogged,
s.invoiced
FROM dbo.project p
LEFT JOIN (
SELECT
projectcode,
SUM(dbo.salesforce.value) AS invoiced
FROM dbo.salesforce
GROUP BY projectcode
) s ON p.projectcode = s.projectcode
LEFT JOIN (
SELECT
projectcode,
SUM(dbo.harvest.hours) AS hourslogged
FROM dbo.harvest
GROUP BY projectcode
) h ON p.projectcode = h.projectcode