2014-08-27 2 views
1

Я пытаюсь создать запрос для подсчета количества кабелей в каждом местоположении активов. Поток - Project-> Asset-> Cable. Один проект может иметь несколько активов с несколькими кабелями, связанными с этими активами. Ниже приведен снимок данных.Oracle SQL Count на основе условий

RECORD_ID PARENT_RECORD_ID FORM_NAME PARENT_FORM FIELD_NAME VALUE 
    1604   1603   asset   project  serial  b345s 
    1604   1603   asset   project  location OH 
    1605   1604   cable   asset   zone  green 
    1606   1603   asset   project  location NY 
    1607   1606   cable   asset   port  2 

Как вы можете видеть выше, на уровне кабеля, то PARENT_RECORD_ID является «record_id» актива. Это всего лишь моментальный снимок, поскольку есть тысячи строк, с рядом данных, но я пытался показывать только соответствующие данные.

Мне нужно выяснить способ свертывания количества кабелей на один актив, а затем группировать активы по «местоположению». «Место» - это значение в столбце FIELD_NAME для актива, со значением, связанным с ним в столбце VALUE. Например, выше, идентификатор актива 1604, «местоположение» - «ОН».

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

SELECT 
    COUNT(DISTINCT RECORD_ID) "Number of Cables" 
FROM 
    PROJECT_TABLE 
WHERE 
    LOWER(FORM_NAME) = 'cable' 

Текущий результат выше запроса:

Number of Cables 
    3137 

То, что я хотел бы результат выглядеть следующим образом:

Location  Number of Cables 
    OH    552 
    NY    1042 
    MI    49 
    CA    1494 

Любая помощь очень ценится! Благодаря!

+0

Ну, в какой колонке находится «местоположение?» – OldProgrammer

+0

Адрес местонахождения? Если это отдельно от той же таблицы, включите ее в свой оператор select. Иначе присоедините его к другой таблице. Кажется прямым, если я не пропущу логику? – programnub112

+0

Прошу прощения, я проясню это в сообщении. «location» - это значение в столбце «FIELD_NAME» для актива. Столбец VALUE в этой же строке имеет состояние, связанное с этим местоположением FIELD_NAME. – ad2387

ответ

1

Это должно сделать трюк.

select 
    ass.VALUE as LOCATION, 
    COUNT(DISTINCT cab.RECORD_ID) as CABLE_COUNT 
from 
    PROJECT_TABLE cab 
    inner join PROJECT_TABLE ass on ass.RECORD_ID = cab.PARENT_RECORD_ID 
where 
    cab.FORM_NAME = 'cable' and 
    ass.FORM_NAME = 'asset' and -- should always be the case? 
    ass.FIELD_NAME = 'location' 
group by 
    ass.VALUE 

Некоторые советы:

  • использовать псевдонимы для таблиц. В этом случае вы должны, потому что одна и та же таблица используется дважды, но я также делаю это, когда мне это не нужно.
  • Если вы используете псевдонимы, убедитесь, что используете аббревиатуры, такие как ass, если вы запрашиваете активы. Это одна из немногих радостей в жизни. :)
  • Я удалил lower. Если это не нужно, оставьте это. Без необходимости вызова функций вы можете полностью использовать индексы, и ваш запрос будет быстрее. Убедитесь, что все значения имеют один и тот же случай, или лучше, сделать таблицу Forms, которая содержит имя с числовым идентификатором, и использовать этот идентификатор в других таблицах. (Google Суррогатные ключи). Кроме того, посмотрите на функциональные индексы. Это позволяет Oracle строить базы индексов для результата функции вместо нормального значения.
  • Если для кабеля есть только одна запись, вам не нужно distinct, и вам не понадобится условие ass.FORM_NAME = 'asset', поэтому ваш запрос будет оптимизирован немного больше.
  • Комбинированный индекс на FORM_NAME и VALUE выгоден, но только до тех пор, пока вам нужны оба условия (см. Комментарий в запросе) и не используйте lower (см. Два замечания выше).
  • В целом, универсальные таблицы, подобные этим, являются плохой практикой. Если у вас есть отдельные таблицы для активов, проектов и местоположений и из них выработана нормализованная модель, у вас будет более удобная и удобная для пользователя модель данных, которую гораздо легче читать и использовать.
+0

Спасибо за ваш ответ. Запрос в настоящее время не возвращает никаких данных, поэтому я изучаю, почему это может быть:/ – ad2387

+0

У меня были 'RECORD_ID' и' PARENT_RECORD_ID' с отсутствующими недочетами. Кроме того, я не понимаю, что не так, но я просто набрал его в «Блокноте», поэтому я мог бы упустить что-то. – GolezTrol

+0

Да, я поймал тех, запрос работает без ошибок. На данный момент ничего не возвращаю. – ad2387