пятница, 16 октября 2009 г.

Анализ данных: DISTINCT vs GROUP BY

При анализе содержимого таблиц часто нужно посмотреть на распределение значений в каком-либо столбце.
Например, чтобы узнать в каких валютах нам выставляют счета поставщики, нужно проанализировать содержимое столбца INVOICE_CURRENCY_CODE таблицы AP_INVOICES_ALL.
Для этого выполняем запрос:

SQL> SELECT   DISTINCT ai.invoice_currency_code
  2    FROM   ap_invoices_all ai;


INVOICE_CURRENC
---------------
RUR
CHF
GBP
EUR
SEK
USD
XDR

Однако это не самое лучшее решение для анализа.
Куда больше информации можно было бы получить переписав запрос так:

  1  SELECT   ai.invoice_currency_code, COUNT(*)
  2    FROM   ap_invoices_all ai
  3*  GROUP BY ROLLUP (ai.invoice_currency_code)
SQL> /


INVOICE_CURRENC   COUNT(*)
--------------- ----------
CHF                     50
EUR                    882
GBP                    153
RUR                 700121
SEK                     45
USD                   5545
XDR                   3641
                    710437

Теперь мы видим не только уникальные коды валют, но и их распределение по строкам, а в конце и общее число записей в таблице(потрясающий эффект от rollup). Да и для Oracle такой запрос совсем не в тягость, тот же объем работы, что и с DISTINCT.

А анализ на этом только начинается.
Увидев распределение значений (особенно когда их много), сразу становится понятно, что для начала нам нужны самые распространенные. Тогда мы добавляем в запрос ORDER BY:

SELECT   ai.invoice_currency_code, COUNT(*)
  FROM   ap_invoices_all ai
 GROUP BY ROLLUP (ai.invoice_currency_code)
 ORDED BY 2 DESC

Если "мелочь" нас не интересует, то отсекаем её при помощи HAVING:

SELECT   ai.invoice_currency_code, COUNT(*)
  FROM   ap_invoices_all ai
 GROUP BY ROLLUP (ai.invoice_currency_code)
 HAVING COUNT(*) > 100


И всего этого мы бы так и не узнали пользуясь обычным DISTINCT.

Нет DISTINCT-у!
Даешь GROUP BY!

P.S. Приведенные результаты запросов - "ненастояшие".

Комментариев нет: