== Напредни теми = Data Cube ( Trade Analytics Cube ) Структурата има 5 димензии: корисник, акција (stock), година, месец и тип на трансакција (BUY/SELL). Со овие димензии се овозможува детална и агрегирана анализа на податоците од различни аспекти. Со користење на GROUP BY CUBE се добиваат сите можни комбинации на овие димензии, што значи дека се формираат вкупно 2⁵ = 32 кубоиди. За секој кубоит се пресметуваат неколку метрики: вкупна вредност на тргувањата (price * quantity), вкупна количина на извршени трансакции и број на трансакции. Редовите каде некоја димензија е NULL претставуваат агрегирани подзбирови, а со користење на GROUPING() функцијата јасно се разликуваат од реални NULL вредности во податоците. Овој пристап овозможува длабинска анализа на пазарното однесување на корисниците и перформансите на акциите низ различни временски периоди. Дополнително, овој Data Cube овозможува лесно откривање на трендови и шаблони во тргувањето, како што се најтргувани акции, најактивни корисници и сезонски промени во активноста. Со тоа се подобрува можноста за донесување аналитички одлуки и подлабоко разбирање на однесувањето на корисниците во системот. {{{ CREATE INDEX idx_tt_user ON trade_transaction(user_id); CREATE INDEX idx_tt_stock ON trade_transaction(stock_id); CREATE INDEX idx_tt_time ON trade_transaction(timestamp); SELECT u.username, s.symbol, EXTRACT(YEAR FROM tt.timestamp) AS year, EXTRACT(MONTH FROM tt.timestamp) AS month, tt.type, SUM(tt.price * tt.quantity) AS total_trade_value, SUM(tt.quantity) AS total_quantity, COUNT(*) AS trade_count, GROUPING(u.username) AS is_all_users, GROUPING(s.symbol) AS is_all_stocks, GROUPING(tt.type) AS is_all_types FROM trade_transaction tt JOIN users u ON tt.user_id = u.id JOIN stock s ON tt.stock_id = s.id GROUP BY CUBE ( u.username, s.symbol, EXTRACT(YEAR FROM tt.timestamp), EXTRACT(MONTH FROM tt.timestamp), tt.type ) ORDER BY u.username, s.symbol; }}} Излез: {{{ username|symbol|year|month|type|total_trade_value |total_quantity|trade_count|is_all_users|is_all_stocks|is_all_types| --------+------+----+-----+----+------------------+--------------+-----------+------------+-------------+------------+ user1 |ALK |2026| 5| | 966688.5368608509| 149| 3| 0| 0| 1| user1 |ALK | | 5| | 966688.5368608509| 149| 3| 0| 0| 1| user1 |ALK | | |SELL| 283321.8072274284| 35| 1| 0| 0| 0| user1 |ALK | | 5|SELL| 283321.8072274284| 35| 1| 0| 0| 0| user1 |ALK | | 5|BUY | 683366.7296334225| 114| 2| 0| 0| 0| user1 |ALK | | |BUY | 683366.7296334225| 114| 2| 0| 0| 0| user1 |ALK |2026| | | 966688.5368608509| 149| 3| 0| 0| 1| }}} Излезот од оваа SQL квери претставува резултат од Data Cube (GROUP BY CUBE), каде податоците се прикажани на повеќе различни нивоа на агрегација истовремено. Тоа значи дека не се прикажуваат само детални записи, туку и збирни вредности за различни комбинации од димензиите: корисник, акција (stock), година, месец и тип на трансакција (BUY/SELL). Редовите каде некои од колоните (година, месец или type) имаат NULL не претставуваат грешка или дупликати, туку означуваат дека тие димензии се агрегирани. На пример, ако колоната type е NULL, тоа значи дека вредностите за BUY и SELL се собрани заедно. Ако месец е NULL, тогаш податоците се агрегирани за целата година итн. Поради тоа, истите вредности на total_trade_value, total_quantity и trade_count може да се појават повеќе пати, бидејќи тие се повторно прикажани за различни нивоа на агрегација (на пример по месец, по година или само по тип на трансакција). Со користење на GROUPING() функцијата јасно се означува кои колони се дел од агрегација, што помага да се разликуваат реални NULL вредности од оние кои настануваат како резултат на Data Cube. Овој пристап овозможува анализа на податоците од повеќе перспективи во исто време.