Необязательные объединения в запросе (... или игнорирование объединения, если поле основной таблицы пустое) - PullRequest
3 голосов
/ 02 марта 2012

У меня есть бюджеты, подобные примеру ниже, где:

  • некоторые бюджеты относятся к конкретному человеку,
  • некоторые предназначены для всей команды, а
  • смесьгде некоторые части выделены конкретному человеку, а остальные - для остальной части команды.

Я могу связать бюджеты с Summary_of_spend, но мне всегда нужно связать год и тип бюджета., но только на человека, если таковой существует в бюджете.Если в бюджете нет человека, просто по умолчанию суммируйте суммы для этой группы.

Как бы я создал объединение, которое для этого?

(Извините, не сталкивался с чем-то подобным и не уверен, как это называется, не говоря уже о том, как это решить. Якстати, используя SQLite.)

Budgets
YEAR, TYPE, PERSON, AMOUNT
2010, Sales, Bob, 1000
2010, Sales, John, 1000
2010, Sales, Fred, 1000
2010, Marketing, Null, 5000
2010, Special, Null, 3000
2010, Special, Bob, 1000
2011, Sales_budget, Bob, 1100
2011, Sales_budget, John, 1100
2011, Sales_budget, Fred, 1100
2011, Marketing, Null, 6000
2010, Special, Null, 3000
2010, Special, Bob, 1000

Spend
DATE, BUDGET, PERSON, AMOUNT
01/01/2010, Sales, Bob, 50
02/01/2010, Marketing, Bob, 100
...

Summary_of_spend
YEAR, BUDGET, PERSON, AMOUNT
2010, Sales, Bob, 950
2010, Sales, John, 888
2010, Marketing, Bob, 500
2010, Marketing, John, 500
2010, Marketing, Fred, 500
2010, Special, Bob, 333
2010, Special, John, 222
2010, Special, Fred, 222
...

Budget_and_summary_of_spend
YEAR, BUDGET_TYPE, PERSON, BUDGET_AMOUNT, SPEND_AMOUNT
2010, Sales, Bob, 1000, 950
2010, Sales, John, 1000, 888
2010, Sales, Fred, 1000, 0
2010, Marketing, Null, 5000, 1500
2010, Special, Null, 3000, 444
2010, Special, Bob, 1000, 333
...

Ответы [ 3 ]

6 голосов
/ 02 марта 2012

Посмотрите на различные типы JOIN s: LEFT OUTER JOIN, вероятно, то, что вам нужно. Левое объединение содержит хотя бы одну строку для каждой строки в левой таблице; если в правой таблице нет совпадений, все ее поля устанавливаются в NULL. Если существует одно или несколько совпадений, оно ведет себя точно так же, как и внутреннее соединение.

Поскольку функция SUM игнорирует значения NULL, группировка и суммирование результатов будут работать как ожидалось.

2 голосов
/ 02 марта 2012

Возможно, вы захотите попробовать это:

from budget inner join summary_of_spend
 on budget.Year = summary_of_spend.Year
   and budget.type = summary_of_spend.Budget
   and ifnull(budget.person, 'ItsDepartment') = ifnull(summary_of_spend.Person, 'ItsDepartment')

Вы можете объединять таблицы на основе любого выражения. В этом случае я присоединился к ним таким образом, что, если человек не равен нулю, у другой стороны должна быть запись для этого человека, и если это значение равно нулю, я подставляю строку, которая не будет найдена среди людей. Это, конечно, слабое место, и если вас это беспокоит, вы можете изменить объединение на комбинацию «и» и «или».

Если вам нужны записи из бюджета, на которые не было потрачено денег, замените «внутреннее объединение» на «левое объединение».

1 голос
/ 05 марта 2012

Спасибо тдаммерам и Николае М. за ответ.Однако, в конце концов, я решил создать союз ... что-то вроде:

Select all the records where there is a budget and a person
UNION ALL
Select all the records where there is only a budget and no specific person
UNION ALL
Select all the remaining records

... и это сработало для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...