Rounding, joins
parent
1e4ded1796
commit
b8eef8a695
33
olap.php
33
olap.php
|
@ -68,6 +68,7 @@ class OLAP
|
||||||
'max' => array('name' => 'Максимум', 'sql' => 'MAX($)'),
|
'max' => array('name' => 'Максимум', 'sql' => 'MAX($)'),
|
||||||
'stddev' => array('name' => 'Дисперсия', 'sql' => 'STDDEV($)'),
|
'stddev' => array('name' => 'Дисперсия', 'sql' => 'STDDEV($)'),
|
||||||
'n_uniq' => array('name' => 'Количество уникальных', 'sql' => 'COUNT(DISTINCT $)'),
|
'n_uniq' => array('name' => 'Количество уникальных', 'sql' => 'COUNT(DISTINCT $)'),
|
||||||
|
'sum_rnd' => array('name' => 'Сумма округлённая', 'sql' => 'ROUND(SUM($))'),
|
||||||
);
|
);
|
||||||
static $group_types = array(
|
static $group_types = array(
|
||||||
'tables' => 'Несколько таблиц',
|
'tables' => 'Несколько таблиц',
|
||||||
|
@ -80,7 +81,7 @@ class OLAP
|
||||||
var $request;
|
var $request;
|
||||||
var $current_srcid, $current_src;
|
var $current_srcid, $current_src;
|
||||||
var $time_start, $nfields, $build, $csv;
|
var $time_start, $nfields, $build, $csv;
|
||||||
var $where, $where_nosql, $group_fields, $cell;
|
var $tables, $where, $where_nosql, $group_fields, $cell;
|
||||||
var $is_html_format = true;
|
var $is_html_format = true;
|
||||||
var $add_spanned;
|
var $add_spanned;
|
||||||
var $graph_scale = 600; /* пикселей */
|
var $graph_scale = 600; /* пикселей */
|
||||||
|
@ -161,10 +162,15 @@ class OLAP
|
||||||
foreach ($v['options'] as &$o)
|
foreach ($v['options'] as &$o)
|
||||||
$v['options_hash'][$o['id']] = $o['name'];
|
$v['options_hash'][$o['id']] = $o['name'];
|
||||||
}
|
}
|
||||||
|
if (is_object($v['sql']) && get_class($v['sql']) === 'Closure')
|
||||||
|
{
|
||||||
|
$v['sql'] = $v['sql']($this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
unset($v);
|
unset($v);
|
||||||
|
|
||||||
// читаем параметры запроса
|
// читаем параметры запроса
|
||||||
|
$this->tables = array();
|
||||||
$this->where = array();
|
$this->where = array();
|
||||||
$this->where_nosql = array();
|
$this->where_nosql = array();
|
||||||
$this->group_fields = array();
|
$this->group_fields = array();
|
||||||
|
@ -187,6 +193,8 @@ class OLAP
|
||||||
}
|
}
|
||||||
if (!$fd || !strlen($v))
|
if (!$fd || !strlen($v))
|
||||||
continue;
|
continue;
|
||||||
|
if (!empty($fd['join']))
|
||||||
|
$this->tables += $fd['join'];
|
||||||
$this->request[$k] = $v;
|
$this->request[$k] = $v;
|
||||||
if (!empty($fd['is_time']))
|
if (!empty($fd['is_time']))
|
||||||
$v = VMXTemplate::timestamp($v, $this->current_src['fielddescs'][$f]['format']);
|
$v = VMXTemplate::timestamp($v, $this->current_src['fielddescs'][$f]['format']);
|
||||||
|
@ -388,15 +396,16 @@ class OLAP
|
||||||
$group_fields = $output[0]['group_by'];
|
$group_fields = $output[0]['group_by'];
|
||||||
$fields = array();
|
$fields = array();
|
||||||
$group_by = array();
|
$group_by = array();
|
||||||
|
$tables = array();
|
||||||
foreach ($group_fields as $i => &$v)
|
foreach ($group_fields as $i => &$v)
|
||||||
{
|
{
|
||||||
$v['sql'] = $this->sql_trans_field($v['field'], $v['func']);
|
$v['sql'] = $this->sql_trans_field($v['field'], $v['func'], $tables);
|
||||||
$v['keys'] = array();
|
$v['keys'] = array();
|
||||||
$fields[] = $v['sql'].' f'.$i;
|
$fields[] = $v['sql'].' f'.$i;
|
||||||
$group_by[] = $v['sql'];
|
$group_by[] = $v['sql'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = $this->sql_trans_field($field, $func);
|
$sql = $this->sql_trans_field($field, $func, $tables);
|
||||||
$fields[] = str_replace('$', $sql, self::$aggregates[$aggr]['sql']).' c';
|
$fields[] = str_replace('$', $sql, self::$aggregates[$aggr]['sql']).' c';
|
||||||
|
|
||||||
$code = 'while($r = $result->fetch_assoc()) { ';
|
$code = 'while($r = $result->fetch_assoc()) { ';
|
||||||
|
@ -410,7 +419,7 @@ class OLAP
|
||||||
$code .= '}';
|
$code .= '}';
|
||||||
|
|
||||||
$result = $this->mysql()->select(
|
$result = $this->mysql()->select(
|
||||||
$this->current_src['tables'], $fields,
|
$this->current_src['tables'] + $this->tables + $tables, $fields,
|
||||||
array_merge($this->current_src['where'], $this->where),
|
array_merge($this->current_src['where'], $this->where),
|
||||||
array('GROUP BY' => $group_by),
|
array('GROUP BY' => $group_by),
|
||||||
MS_RESULT
|
MS_RESULT
|
||||||
|
@ -876,9 +885,11 @@ class OLAP
|
||||||
return $c;
|
return $c;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sql_trans_field($field, $func)
|
function sql_trans_field($field, $func, &$tables)
|
||||||
{
|
{
|
||||||
$fd = &$this->current_src['fielddescs'][$field];
|
$fd = &$this->current_src['fielddescs'][$field];
|
||||||
|
if (!empty($fd['join']))
|
||||||
|
$tables += $fd['join'];
|
||||||
if (empty($field) && $field !== '0')
|
if (empty($field) && $field !== '0')
|
||||||
$sql = '1';
|
$sql = '1';
|
||||||
else
|
else
|
||||||
|
@ -987,6 +998,18 @@ class OLAP
|
||||||
$aggr += $value;
|
$aggr += $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Сумма округлённая - обновление
|
||||||
|
static function aggr_update_sum_rnd(&$aggr, &$value)
|
||||||
|
{
|
||||||
|
$aggr += $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сумма округлённая - обновление
|
||||||
|
static function aggr_finish_sum_rnd(&$aggr)
|
||||||
|
{
|
||||||
|
$aggr = round($aggr);
|
||||||
|
}
|
||||||
|
|
||||||
// Среднее - обновление
|
// Среднее - обновление
|
||||||
static function aggr_update_avg(&$aggr, &$value)
|
static function aggr_update_avg(&$aggr, &$value)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
function v2tags_get_tags()
|
|
||||||
{
|
|
||||||
return mysql_select('tags', 'id, name', array('type' => 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
OLAP::$sources = array(
|
OLAP::$sources = array(
|
||||||
'mediawiki_history' => array(
|
'mediawiki_history' => array(
|
||||||
'id' => 'mediawiki_history',
|
'id' => 'mediawiki_history',
|
||||||
|
@ -36,7 +31,10 @@ OLAP::$sources = array(
|
||||||
),
|
),
|
||||||
'tag' => array(
|
'tag' => array(
|
||||||
'name' => 'Тег',
|
'name' => 'Тег',
|
||||||
'options' => 'v2tags_get_tags',
|
'options' => function($olap)
|
||||||
|
{
|
||||||
|
return $olap->mysql()->select('tags', 'id, name', array('type' => 0));
|
||||||
|
}
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -76,15 +74,41 @@ OLAP::$sources = array(
|
||||||
'bugzilla' => array(
|
'bugzilla' => array(
|
||||||
'id' => 'bugzilla',
|
'id' => 'bugzilla',
|
||||||
'name' => 'Время Bugzilla',
|
'name' => 'Время Bugzilla',
|
||||||
'tables' => array('t' => 'bugs3.longdescs', 'p' => 'bugs3.profiles'),
|
'tables' => array(
|
||||||
|
't' => 'bugs3.longdescs',
|
||||||
|
'p' => [ 'INNER', 'bugs3.profiles', [ 'p.userid=t.who' ] ],
|
||||||
|
'b' => [ 'INNER', 'bugs3.bugs', [ 'b.bug_id=t.bug_id' ] ],
|
||||||
|
'pr' => [ 'INNER', 'bugs3.products', [ 'pr.id=b.product_id' ] ],
|
||||||
|
'c' => [ 'INNER', 'bugs3.components', [ 'c.id=b.component_id' ] ],
|
||||||
|
'bt' => [ 'LEFT', 'bugs3.cf_bug_type', [ 'bt.id=b.cf_bug_type' ] ],
|
||||||
|
),
|
||||||
'fields' => 'p.login_name, t.bug_when, t.work_time',
|
'fields' => 'p.login_name, t.bug_when, t.work_time',
|
||||||
'where' => array('t.who=p.userid'),
|
'where' => array(
|
||||||
|
'p.login_name like "%@custis.ru"',
|
||||||
|
),
|
||||||
'fielddescs' => array(
|
'fielddescs' => array(
|
||||||
'login_name' => array(
|
'group' => array(
|
||||||
'name' => 'Сотрудник',
|
'name' => 'Группа',
|
||||||
|
'join' => [
|
||||||
|
'ug' => [ 'INNER', 'bugs3.user_group_map', [ 'ug.user_id=t.who', 'ug.isbless=0' ] ],
|
||||||
|
'g' => [ 'INNER', 'bugs3.groups', [ 'g.id=ug.group_id' ] ],
|
||||||
|
],
|
||||||
|
'sql' => 'g.id',
|
||||||
|
'options' => function($olap)
|
||||||
|
{
|
||||||
|
return $olap->mysql()->select('bugs3.groups', 'id, name', array('isbuggroup=1'), array('ORDER BY' => 'name'));
|
||||||
|
}
|
||||||
|
),
|
||||||
|
'who' => array(
|
||||||
|
'name' => 'Логин',
|
||||||
|
'sql' => 'p.login_name',
|
||||||
|
/* 'options' => function($olap)
|
||||||
|
{
|
||||||
|
return $olap->mysql()->select('bugs3.profiles', 'userid id, login_name name', array('login_name like "%@custis.ru" and realname not like \'Группа%\''));
|
||||||
|
}*/
|
||||||
),
|
),
|
||||||
'bug_when' => array(
|
'bug_when' => array(
|
||||||
'name' => 'Момент',
|
'name' => 'Момент времени',
|
||||||
'le_ge' => true,
|
'le_ge' => true,
|
||||||
'is_time' => true,
|
'is_time' => true,
|
||||||
'format' => TS_DB,
|
'format' => TS_DB,
|
||||||
|
@ -93,6 +117,40 @@ OLAP::$sources = array(
|
||||||
'name' => 'Часы',
|
'name' => 'Часы',
|
||||||
'le_ge' => true,
|
'le_ge' => true,
|
||||||
),
|
),
|
||||||
|
'bug_id' => array(
|
||||||
|
'name' => 'ID бага',
|
||||||
|
'sql' => 't.bug_id',
|
||||||
|
'le_ge' => true,
|
||||||
|
),
|
||||||
|
'product' => array(
|
||||||
|
'name' => 'Продукт',
|
||||||
|
'sql' => 'pr.name',
|
||||||
|
),
|
||||||
|
'component' => array(
|
||||||
|
'name' => 'Компонент',
|
||||||
|
'sql' => 'c.name',
|
||||||
|
),
|
||||||
|
'cf_bug_type' => array(
|
||||||
|
'name' => 'Тип бага',
|
||||||
|
'sql' => 'bt.value',
|
||||||
|
),
|
||||||
|
'da_type' => array(
|
||||||
|
'name' => 'Время ДА',
|
||||||
|
'sql' => function($olap)
|
||||||
|
{
|
||||||
|
$arch_product = $olap->mysql()->select('bugs3.products', 'id', [ 'name' => '-Arch_Other' ], NULL, MS_VALUE);
|
||||||
|
$arch_components = $olap->mysql()->select('bugs3.components', 'id', [ 'name LIKE ?' => 'arch%' ], NULL, MS_COL);
|
||||||
|
$arch_bug_types = $olap->mysql()->select('bugs3.cf_bug_type', 'id', [ 'value LIKE ?' => 'arch%' ], NULL, MS_COL);
|
||||||
|
return '(CASE'.
|
||||||
|
($arch_product ? ' WHEN b.product_id='.$arch_product.' THEN \'ДА\'' : '').
|
||||||
|
($arch_components || $arch_bug_types ? ' WHEN '.
|
||||||
|
($arch_components ? 'b.component_id IN ('.implode(',', $arch_components).')' : '').
|
||||||
|
($arch_components && $arch_bug_types ? ' OR ' : '').
|
||||||
|
($arch_bug_types ? 'b.cf_bug_type IN ('.implode(',', $arch_bug_types).')' : '').
|
||||||
|
' THEN \'Арх\'' : '').
|
||||||
|
' ELSE \'Другое\' END)';
|
||||||
|
}
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -19,7 +19,7 @@ p { margin: 4px 0; }
|
||||||
.themes li { padding: 0; display: inline; margin-right: 8px; }
|
.themes li { padding: 0; display: inline; margin-right: 8px; }
|
||||||
.simpletable, .simpletable td { border: 1px solid black; }
|
.simpletable, .simpletable td { border: 1px solid black; }
|
||||||
.simpletable { border-collapse: collapse; }
|
.simpletable { border-collapse: collapse; }
|
||||||
.simpletable.center td { text-align: center; }
|
.simpletable.center td { text-align: right; }
|
||||||
.simpletable td ul { padding: 0 6px 0 20px; }
|
.simpletable td ul { padding: 0 6px 0 20px; }
|
||||||
.simpletable td li { text-align: left; }
|
.simpletable td li { text-align: left; }
|
||||||
.simpletable th { padding: 3px 8px; background-color: #a0a0a0; vertical-align: top; }
|
.simpletable th { padding: 3px 8px; background-color: #a0a0a0; vertical-align: top; }
|
||||||
|
|
Loading…
Reference in New Issue