|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
На главную | Книги | Ссылки | Рассылка | Письмо автору | RSS | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
Если мы хотим увидеть, сколько клиентов у нас в каждом маркетинговом регионе, внутреннее соединение даст нам следующий результат:
Внутреннее соединение является соединением "по равенству". Поскольку для почтового индекса 24166 нет эквивалентного маркетингового региона, запрос недосчитывает наших подписчиков, возвращая четырёх клиентов, вместо пяти. Мы также теряем информацию с другой стороны соединения, поскольку в результате запроса отсутствуют данные о регионах, в которых у нас нет клиентов (например, Gloucester). Переписав запрос с использованием полного внешнего соединения, мы получим следующий результат:
Теперь мы посчитали всех пятерых клиентов и увидели, что в регионе Gloucester они отсутствуют. Мы могли бы использовать функцию IFNULL для замены значения NULL на более дружественные значения, например, "неизвестный регион". Заметьте, то, что вы считаете, сильно влияет на результаты. В нашем случае мы считали значения столбца Customer_Key. Если бы мы заменили это на count(*), мы могли бы в результате получить 7, поскольку * означает подсчёт всех строк, а полный результат состоит из семи строк. Если бы мы стали считать количество значений столбца MMA_to_Zipcode.Zip_Code, мы насчитали бы 6 значений, поскольку значение 94025 встречается два раза. При использовании внешних соединений надо проявлять осторожность, можно легко разрушить логику, введя ограничение на одну из участвующих в соединении таблиц. Ограничение вида Customer_Age<25 привело бы к отчёту с абсолютно идентичной структурой и заголовками, но с меньшим количеством клиентов. Отчёт будет сбивать с толку, если явно не проставить названия. Мы обнаружили, что комбинирование выражения CASE с функцией SUM является отличной хитростью, позволяющей выполнять в один проход подсчёт строк различных подмножеств полных результирующих наборов данных с обеих сторон полного внешнего соединения. Используя те же самые данные, что и в примерах выше, мы могли бы создать запрос, который возвратит нам полное количество записей для всех трёх областей набора данных. В операторе SELECT вы бы написали: Sum(case when Media_Market_Area.Zip IS NULL then 1 else 0 end) AS Customer_Count_with_No_MMA, Sum(case when count(customer_key)=0 then 1 else 0 end) as MMA_Count_with_No_Customers, Sum(case when not(Media_Market_Area.Zip IS NULL or count(customer_key)=0) then 1 else 0 end as Count_MMAs_with_Customers) Это даёт вам три столбца: количество клиентов, для которых отсутствуют маркетинговые регионы, количество маркетинговых регионов, в которых у нас нет клиентов, а также сумму для имеющихся совпадений. В сущности, ограничения встроены внутрь выражений CASE, поэтому они не ограничивают результатов внешнего соединения.
По этой теме можно также почитать: Для удобства отслеживания новых публикаций на сайте рекомендую подписаться на рассылку или подписаться на канал RSS. Если вы нашли в сети интересные ссылки на ресурсы по технологиям хранилищ данных, OLAP, CRM или data mining, и хотите поделиться ими с другими, присылайте их. Я с удовольствием размещу их на этом сайте.
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||
[ На главную | Книги | Ссылки | Рассылка | Письмо автору | Реклама на сайте ] © Константин Лисянский, 2001-2008.
|