SQL для начинающих: несколько предложений where из одной таблицы

Я очень новичок в SQL и не знаю, как выполнить следующее.

У меня есть список идентификаторов счетчиков, которым назначены данные о цели за годы и данные о бюджете за годы, однако все они хранятся в одной таблице с идентификатором (TargetType), чтобы различать цель (0) и бюджет (1)

ID   TARGETTYPE   VALUE01   VALUE02 ...(etc up to VALUE12)
123  0            1001      1100
123  1            9000      9100
456  0            5000      5100
456  1            8000      8100      

Желаемый результат также будет включать информацию из нескольких других таблиц, которые вы также хотите добавить.

Мой запрос до сих пор может передать один набор данных:

PARAMETERS 
[Utility] Text;

SELECT 
Contacts.Group,
Contacts.Site,
Points.ID,
Points.Utility,
Points.MPAN1,
Target.Value_01 AS [Target JAN],
Target.Value_02 AS [Target FEB],
Target.Value_03 AS [Target MAR],
Target.Value_04 AS [Target APR],
Target.Value_05 AS [Target MAY],
Target.Value_06 AS [Target JUN],
Target.Value_07 AS [Target JUL],
Target.Value_08 AS [Target AUG],
Target.Value_09 AS [Target SEP],
Target.Value_10 AS [Target OCT],
Target.Value_11 AS [Target NOV],
Target.Value_12 AS [Target DEC]

FROM 
((Contacts INNER JOIN Points ON Contacts.[Id] = Points.[Contacts_Id]) 
                  INNER JOIN Contracts ON Points.[Id] = Contracts.[Point_Id]) 
                  INNER JOIN Target ON Points.Id = Target.DataSetId

WHERE 
Points.UtilityType =[Utility]

ORDER BY 
Contacts.ClientGroup;

Желаемый результат
(значения должны пройти от TargetJan до TargetDec, а затем от BudgetJan до BudgetDec, но я не показал для краткости):

Group Site     ID   Utility MPAN1    TargetJan TargetFeb etc... BudgetJan  BudgetFeb etc...      
ABC   London   123  Gas     123456    1,000     1,100           9,000      9,100
ABC   NewYork  456  Gas     ABC123    5,000     5,100           8,000      8,100 

Как я могу добавить в те же поля, но в зависимости от значения Target.TargetType, я предполагаю, что это запрос на объединение, но я понятия не имею.

Любые указатели того, с чего начать, будут с благодарностью получены :)


ОБНОВЛЕНИЕ №1
Спасибо за помощь. Я думаю, что понимаю запрос, однако все еще есть немного странного поведения, которое я не могу понять.

ИСПОЛЬЗУЕМЫЙ ЗАПРОС

SELECT 
Points.ID,

  SUM(CASE WHEN Target.TargetType = '0' THEN Target.Value_01 else 0 end) AS [TGT JAN],
  SUM(CASE WHEN Target.TargetType = '0' THEN Target.Value_02 else 0 end) AS [TGT FEB],

FROM 
((Contacts INNER JOIN Points ON Contacts.[Id] = Points.[Contacts_Id]) 
              INNER JOIN Contracts ON Points.[Id] = Contracts.[Point_Id] )
              INNER JOIN Target ON Points.Id = Target.DataSetId

GROUP BY
Points.ID

ORDER BY
Points.ID;


Если моя строка данных имеет только один Target.Type, то запрос возвращает желаемое:
НЕОБРАБОТАННЫЕ ДАННЫЕ

ID     TARGETTYPE   VALUE_01   VALUE_02 
10079  0            7642      5735

РЕЗУЛЬТАТ

ID    TGTJAN   TGTFEB
10079 7642    5735

Однако... Если у меня есть идентификатор с 2 или более TargetTypes, то выходное значение умножается на 6.

НЕОБРАБОТАННЫЕ ДАННЫЕ

ID     TARGETTYPE   VALUE_01   VALUE_02 
7423   0            58339     57441
7423   1            1663      1637

РЕЗУЛЬТАТ

ID    TGTJAN   TGTFEB
7423  350034   344646

Я поэкспериментировал и удалил ВНУТРЕННЕЕ СОЕДИНЕНИЕ с таблицей контактов (хотя это соединение мне понадобится), и тогда все работает как положено ???? Так почему же Contacts JOIN вызывает эту проблему?

Пожалуйста, избавьте меня от страданий, так как я не могу понять, что происходит!


person CatParky    schedule 27.08.2015    source источник
comment
Можете ли вы отредактировать свой вопрос и добавить пример желаемых результатов?   -  person Tab Alleman    schedule 27.08.2015
comment
И, пожалуйста, сообщите нам, какую СУБД вы используете. SQL — это просто язык запросов, а не конкретный продукт СУБД. И в вашем примере используется нестандартный синтаксис (похоже на SQL Server/T-SQL)   -  person a_horse_with_no_name    schedule 27.08.2015
comment
Я считаю, что это SQL Server, как это указано в справочном документе.   -  person CatParky    schedule 27.08.2015
comment
Union будет работать, а затем сортировать по группам   -  person nomistic    schedule 27.08.2015


Ответы (2)


Как насчет использования синтаксиса выбора регистра?

select
...
sum(case when Target.TargetType = 'Target' then Target.Value_01 else 0 end) AS [Target JAN],
sum(case when Target.TargetType = 'Budget' then Target.Value_01 else 0 end) AS [Budget JAN],
...
group by
--all fields in the select list which are not aggregates
person Gabor    schedule 27.08.2015
comment
Спасибо, это определенно дало мне отправную точку! Однако 1) я получаю ошибки, когда использую часть запроса SUM 2) я получаю повторяющиеся строки для каждого идентификатора, а не значения в одной строке для каждого идентификатора - person CatParky; 27.08.2015
comment
ОШИБКА: столбец «Points.Id» недействителен в списке выбора, поскольку он не содержится ни в агрегатной функции, ни в предложении GROUP BY. ВЫБЕРИТЕ Points.ID, Contacts.Text_7, Contacts.Name, sum(случай, когда Target.TargetType = '0', затем Target.Value_01, иначе 0 end) AS [TGT kWh JAN] FROM ((Contacts INNER JOIN Points ON Contacts.[Id ] = Points.[Contacts_Id]) INNER JOIN Contracts ON Points.[Id] = Contracts.[Point_Id]) INNER JOIN Target ON Points.Id = Target.DataSetId ORDER BY Contacts.Text_7; СГРУППИРОВАТЬ ПО Points.ID, Contacts.Text_7, Contacts.Name; - person CatParky; 27.08.2015
comment
Я уже говорил вам в моем примере: вы должны поместить все поля в предложение group by, которые находятся в списке выбора, которые не являются агрегатами. - person Gabor; 27.08.2015
comment
Теперь я вижу вашу ошибку: 1: удалите ; знак между порядком и групповым предложением, и правильный порядок - это группа, чем порядок по - person Gabor; 27.08.2015

Для справки в будущем я решил эту проблему, переписав объединения и изменив способ хранения данных, поэтому мне не нужно ссылаться на таблицу Contracts, которая является избыточной и, вероятно, способствовала моей странной проблеме с x на 6.

SELECT 
Points.ID,

  SUM(CASE WHEN Target.TargetType = '0' THEN Target.Value_01 else 0 end) AS [TGT kWh JAN],
  SUM(CASE WHEN Target.TargetType = '0' THEN Target.Value_02 else 0 end) AS [TGT kWh FEB],

  SUM(CASE WHEN Target.TargetType = '1' THEN Target.Value_01 else 0 end) AS [BUD kWh JAN],
  SUM(CASE WHEN Target.TargetType = '1' THEN Target.Value_02 else 0 end) AS [BUD kWh FEB]

FROM (Contacts INNER JOIN Points ON Contacts.Id = Points.Contacts_Id)  
                       INNER JOIN Target ON Points.Id = Target.DataSetId

GROUP BY
Points.ID

ORDER BY
Points.ID;
person CatParky    schedule 01.09.2015