cell_group_field
parent
e9ab8df823
commit
2b9454371a
|
@ -894,9 +894,9 @@ $iset";
|
|||
}
|
||||
|
||||
/* ключи хеша или массива */
|
||||
function function_keys($a) { return "array_keys($a)"; }
|
||||
function function_hash_keys($a) { return "array_keys($a)"; }
|
||||
function function_array_keys($a) { return "array_keys($a)"; }
|
||||
function function_keys($a) { return "array_keys(is_array($a) ? $a : array())"; }
|
||||
function function_hash_keys($a) { return "array_keys(is_array($a) ? $a : array())"; }
|
||||
function function_array_keys($a) { return "array_keys(is_array($a) ? $a : array())"; }
|
||||
|
||||
// создание массива
|
||||
function function_array()
|
||||
|
@ -917,9 +917,9 @@ $iset";
|
|||
|
||||
// получить элемент хеша/массива по неконстантному ключу (например get(iteration.array, rand(5)))
|
||||
// по-моему, это лучше, чем Template Toolkit'овский ад - hash.key.${another.hash.key}.зюка.хрюка и т.п.
|
||||
function function_get($a, $k) { return $a."[$k]"; }
|
||||
function function_hget($a, $k) { return $a."[$k]"; }
|
||||
function function_aget($a, $k) { return $a."[$k]"; }
|
||||
function function_get($a, $k=NULL) { if ($k !== NULL) return $a."[$k]"; return "\$this->tpldata[$a]"; }
|
||||
function function_hget($a, $k=NULL) { if ($k !== NULL) return $a."[$k]"; return "\$this->tpldata[$a]"; }
|
||||
function function_aget($a, $k=NULL) { if ($k !== NULL) return $a."[$k]"; return "\$this->tpldata[$a]"; }
|
||||
|
||||
// shift, unshift, pop, push
|
||||
function function_shift($a) { return "array_shift($a)"; }
|
||||
|
|
62
olap.php
62
olap.php
|
@ -33,10 +33,15 @@ class OLAP
|
|||
'min' => array('name' => 'Минимум', 'sql' => 'MIN($)'),
|
||||
'max' => array('name' => 'Максимум', 'sql' => 'MAX($)'),
|
||||
'stddev' => array('name' => 'Дисперсия', 'sql' => 'STDDEV($)'),
|
||||
'distinct' => array('name' => 'Значения', 'cell_only' => true),
|
||||
'n_uniq' => array('name' => 'Количество уникальных', 'sql' => 'COUNT(DISTINCT $)'),
|
||||
# 'equally' => array('name' => '', ),
|
||||
);
|
||||
static $specf = array(
|
||||
'v_field', 'v_func', 'h_field', 'h_func',
|
||||
'cell_field', 'cell_aggr', 'cell_func', 'cell_group_field', 'cell_group_func',
|
||||
'v_sort_dir', 'v_sort_field', 'v_sort_aggr', 'v_sort_func',
|
||||
'h_sort_dir', 'h_sort_field', 'h_sort_aggr', 'h_sort_func',
|
||||
);
|
||||
static $specf = array('v_field', 'v_func', 'h_field', 'h_func', 'cell_field', 'cell_aggr', 'cell_func', 'v_sort_dir', 'v_sort_field', 'v_sort_aggr', 'v_sort_func', 'h_sort_dir', 'h_sort_field', 'h_sort_aggr', 'h_sort_func');
|
||||
|
||||
static function execute($request)
|
||||
{
|
||||
|
@ -83,15 +88,16 @@ class OLAP
|
|||
$wh["value-$i"] = $v;
|
||||
if ($fd['is_time'])
|
||||
$v = Template::timestamp($v, self::$current_src['fielddefs'][$f]['format']);
|
||||
$dn = $fd['dbname'];
|
||||
$dn = $fd['sql'];
|
||||
if (!$dn)
|
||||
$dn = $f;
|
||||
$v = mysql_ecranize($v);
|
||||
if ($t == 'eq')
|
||||
$where[$dn] = $v;
|
||||
$where[] = "$dn = $v";
|
||||
elseif ($t == 'ge')
|
||||
$where[] = "$dn >= ".mysql_ecranize($v);
|
||||
$where[] = "$dn >= $v";
|
||||
elseif ($t == 'le')
|
||||
$where[] = "$dn <= ".mysql_ecranize($v);
|
||||
$where[] = "$dn <= $v";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,6 +137,12 @@ class OLAP
|
|||
$fields[] = $h_sql.' h_field';
|
||||
$options['GROUP BY'][] = $h_sql;
|
||||
}
|
||||
if ($cell_group_field !== '')
|
||||
{
|
||||
$cg_sql = self::sql_trans_field($cell_group_field, $cell_group_func);
|
||||
$fields[] = $cg_sql.' cell_group_field';
|
||||
$options['GROUP BY'][] = $cg_sql;
|
||||
}
|
||||
$cell_sql = self::sql_trans_field($cell_field, $cell_func);
|
||||
if (self::$aggregates[$cell_aggr]['sql'])
|
||||
$fields[] = str_replace('$', $cell_sql, self::$aggregates[$cell_aggr]['sql']).' cell_field';
|
||||
|
@ -147,16 +159,28 @@ class OLAP
|
|||
$hkeys = array();
|
||||
while ($r = mysql_fetch_assoc($result))
|
||||
{
|
||||
$v = &$group[$r['v_field']][$r['h_field']];
|
||||
if ($cell_group_field !== '')
|
||||
$v = &$v[$r['cell_group_field']];
|
||||
if ($do_aggr)
|
||||
call_user_func_array('self::aggr_update_'.$cell_aggr, array(&$group[$r['v_field']][$r['h_field']], &$r['cell_field']));
|
||||
call_user_func_array('self::aggr_update_'.$cell_aggr, array(&$v, &$r['cell_field']));
|
||||
else
|
||||
$group[$r['v_field']][$r['h_field']] = $r['cell_field'];
|
||||
$v = $r['cell_field'];
|
||||
$hkeys[$r['h_field']] = 1;
|
||||
}
|
||||
unset($v);
|
||||
if ($do_aggr && is_callable('self::aggr_finish_'.$cell_aggr))
|
||||
foreach ($group as $i => &$r)
|
||||
foreach ($r as $j => &$c)
|
||||
call_user_func_array('self::aggr_finish_'.$cell_aggr, array(&$c));
|
||||
{
|
||||
if ($cell_group_field !== '')
|
||||
foreach ($group as $i => &$r)
|
||||
foreach ($r as $j => &$c)
|
||||
call_user_func_array('self::aggr_finish_'.$cell_aggr, array(&$c));
|
||||
else
|
||||
foreach ($group as $i => &$r)
|
||||
foreach ($r as $j => &$c)
|
||||
foreach ($c as $k => &$g)
|
||||
call_user_func_array('self::aggr_finish_'.$cell_aggr, array(&$g));
|
||||
}
|
||||
|
||||
if ($v_field !== '' && $v_sort_aggr !== '' && $v_sort_field !== '')
|
||||
{
|
||||
|
@ -215,9 +239,11 @@ class OLAP
|
|||
|
||||
static function sql_trans_field($field, $func)
|
||||
{
|
||||
$fd = &self::$current_src['fielddescs'][$field];
|
||||
$sql = $field;
|
||||
if (self::$current_src['fielddescs'][$field]['is_time'] &&
|
||||
self::$current_src['fielddescs'][$field]['format'] == TS_UNIX &&
|
||||
if ($fd['sql'])
|
||||
$sql = $fd['sql'];
|
||||
if ($fd['is_time'] && $fd['format'] == TS_UNIX &&
|
||||
(!self::$functions[$func] || self::$functions[$func]['time_format']))
|
||||
$sql = "FROM_UNIXTIME($sql)";
|
||||
if (self::$functions[$func])
|
||||
|
@ -256,15 +282,7 @@ class OLAP
|
|||
static function field_format($field, $func, $aggr, $value)
|
||||
{
|
||||
$o = &self::$current_src['fielddescs'][$field]['options_hash'];
|
||||
if ($aggr == 'distinct')
|
||||
{
|
||||
$r = '';
|
||||
if ($value)
|
||||
foreach($value as $k => $n)
|
||||
$r .= self::field_format($field, $func, false, $k).': '.$n.(self::$is_html_format ? "<br />" : "")."\n";
|
||||
return $r;
|
||||
}
|
||||
elseif ($o && $o[$value])
|
||||
if ($o && $o[$value])
|
||||
return $o[$value];
|
||||
elseif (preg_match('/^-?\d+\.\d+$/s', $value))
|
||||
return sprintf(self::$decimal, $value);
|
||||
|
|
|
@ -19,18 +19,7 @@
|
|||
<table>
|
||||
<tr><td style="text-align: center; vertical-align: middle"><input type="submit" value=" Построить отчёт " /></td><td style="background-color: #e0e0e0; padding: 8px">
|
||||
По горизонтали:<br />
|
||||
<select style="width:100px" name="h_field">
|
||||
<option value="">---</option>
|
||||
<!-- FOR f = fielddescs -->
|
||||
<option value="{s f.id}"<!-- IF eq(h_field, f.id) --> selected<!-- END -->>{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
<select style="width:100px" name="h_func">
|
||||
<option value="">без преобразования</option>
|
||||
<!-- FOR f = functions -->
|
||||
<option value="{s f.id}"<!-- IF eq(h_func, f.id) --> selected<!-- END -->><!-- IF f.time -->(время) <!-- END -->{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select><br />
|
||||
<!-- SET fld = 'h' --><!-- INCLUDE admin_olap_field.tpl --><br />
|
||||
Сортировка:<br />
|
||||
<select style="width:100px" name="h_sort_dir">
|
||||
<option value="asc">по возрастанию</option>
|
||||
|
@ -39,38 +28,14 @@
|
|||
<select style="width:100px" name="h_sort_aggr">
|
||||
<option value="">по значениям поля</option>
|
||||
<!-- FOR f = aggregates -->
|
||||
<!-- IF NOT f.cell_only -->
|
||||
<option value="{s f.id}"<!-- IF eq(h_sort_aggr, f.id) --> selected<!-- END -->>{s f.name} другого поля:</option>
|
||||
<!-- END -->
|
||||
<!-- END -->
|
||||
</select>
|
||||
<select style="width:100px" name="h_sort_field">
|
||||
<option value="">---</option>
|
||||
<!-- FOR f = fielddescs -->
|
||||
<option value="{s f.id}"<!-- IF eq(h_sort_field, f.id) --> selected<!-- END -->>{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
<select style="width:100px" name="h_sort_func">
|
||||
<option value="">без преобразования</option>
|
||||
<!-- FOR f = functions -->
|
||||
<option value="{s f.id}"<!-- IF eq(h_sort_func, f.id) --> selected<!-- END -->><!-- IF f.time -->(время) <!-- END -->{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
</select>
|
||||
<!-- SET fld = 'h_sort' --><!-- INCLUDE admin_olap_field.tpl -->
|
||||
</td></tr>
|
||||
<tr><td style="background-color: #e0e0e0; padding: 8px">
|
||||
По вертикали:<br />
|
||||
<select style="width:100px" name="v_field">
|
||||
<option value="">---</option>
|
||||
<!-- FOR f = fielddescs -->
|
||||
<option value="{s f.id}"<!-- IF eq(v_field, f.id) --> selected<!-- END -->>{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
<select style="width:100px" name="v_func">
|
||||
<option value="">без преобразования</option>
|
||||
<!-- FOR f = functions -->
|
||||
<option value="{s f.id}"<!-- IF eq(v_func, f.id) --> selected<!-- END -->><!-- IF f.time -->(время) <!-- END -->{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select><br />
|
||||
<!-- SET fld = 'v' --><!-- INCLUDE admin_olap_field.tpl --><br />
|
||||
Сортировка:<br />
|
||||
<select style="width:100px" name="v_sort_dir">
|
||||
<option value="asc">по возрастанию</option>
|
||||
|
@ -79,41 +44,20 @@
|
|||
<select style="width:100px" name="v_sort_aggr">
|
||||
<option value="">по значениям поля</option>
|
||||
<!-- FOR f = aggregates -->
|
||||
<!-- IF NOT f.cell_only -->
|
||||
<option value="{s f.id}"<!-- IF eq(v_sort_aggr, f.id) --> selected<!-- END -->>{s f.name} другого поля:</option>
|
||||
<!-- END -->
|
||||
<!-- END -->
|
||||
</select>
|
||||
<select style="width:100px" name="v_sort_field">
|
||||
<option value="">---</option>
|
||||
<!-- FOR f = fielddescs -->
|
||||
<option value="{s f.id}"<!-- IF eq(v_sort_field, f.id) --> selected<!-- END -->>{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
<select style="width:100px" name="v_sort_func">
|
||||
<option value="">без преобразования</option>
|
||||
<!-- FOR f = functions -->
|
||||
<option value="{s f.id}"<!-- IF eq(v_sort_func, f.id) --> selected<!-- END -->><!-- IF f.time -->(время) <!-- END -->{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
</select>
|
||||
<!-- SET fld = 'v_sort' --><!-- INCLUDE admin_olap_field.tpl -->
|
||||
</td><td style="background-color: #ffe0e0; padding: 8px">
|
||||
В таблице:<br />
|
||||
<select style="width:100px" name="cell_aggr">
|
||||
<!-- FOR f = aggregates -->
|
||||
<option value="{s f.id}"<!-- IF eq(cell_aggr, f.id) --> selected<!-- END -->>{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
<select style="width:100px" name="cell_field">
|
||||
<!-- FOR f = fielddescs -->
|
||||
<option value="{s f.id}"<!-- IF eq(cell_field, f.id) --> selected<!-- END -->>{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
<select style="width:100px" name="cell_func">
|
||||
<option value="">без преобразования</option>
|
||||
<!-- FOR f = functions -->
|
||||
<option value="{s f.id}"<!-- IF eq(cell_func, f.id) --> selected<!-- END -->><!-- IF f.time -->(время) <!-- END -->{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
</select>
|
||||
<!-- SET fld = 'cell' --><!-- INCLUDE admin_olap_field.tpl --><br />
|
||||
Дополнительно разбить по:<br />
|
||||
<!-- SET fld = 'cell_group' --><!-- INCLUDE admin_olap_field.tpl --><br />
|
||||
</td></tr>
|
||||
</table>
|
||||
Условия выборки данных:
|
||||
|
@ -150,10 +94,28 @@
|
|||
<!-- IF NOT data -->
|
||||
<p>Нет данных для показа.</p>
|
||||
<!-- ELSE -->
|
||||
<!-- SET hascg = strlen(cell_group_field) -->
|
||||
<table class="simpletable">
|
||||
<tr><th></th><!-- FOR k = hkeys --><th>{fformat(h_field,h_func,'',k)}</th><!-- END --><!-- IF vsort --><th></th><!-- END --></tr>
|
||||
<tr><th></th><!-- FOR k = hkeys --><th>{fformat(h_field,h_func,'',k)}</th><!-- END --><!-- IF vsort --><th></th><!-- END --></tr>
|
||||
<!-- FOR v = vkeys -->
|
||||
<tr><th>{fformat(v_field,v_func,'',v)}</th><!-- FOR k = hkeys --><td>{fformat(cell_field,cell_func,cell_aggr,get(get(data,v),k))}</td><!-- END --><!-- IF vsort --><th>{get(vsort,v)}</th><!-- END --></tr>
|
||||
<tr>
|
||||
<th>{fformat(v_field,v_func,'',v)}</th>
|
||||
<!-- FOR k = hkeys -->
|
||||
<td>
|
||||
<!-- SET cv = get(get(data,v),k) -->
|
||||
<!-- IF hascg -->
|
||||
<!-- FOR ck = keys(cv) -->
|
||||
{fformat(cell_group_field,cell_group_func,'',ck)}: {fformat(cell_field,cell_func,cell_aggr,get(cv,ck))}<br />
|
||||
<!-- END -->
|
||||
<!-- ELSE -->
|
||||
{fformat(cell_field,cell_func,cell_aggr,cv)}
|
||||
<!-- END -->
|
||||
</td>
|
||||
<!-- END -->
|
||||
<!-- IF vsort -->
|
||||
<th>{get(vsort,v)}</th>
|
||||
<!-- END -->
|
||||
</tr>
|
||||
<!-- END -->
|
||||
<!-- IF hsort -->
|
||||
<tr><th></th><!-- FOR k = hkeys --><th>{get(hsort,k)}</th><!-- END --><!-- IF vsort --><th></th><!-- END --></tr>
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<select style="width:100px" name="{fld}_field">
|
||||
<option value="">---</option>
|
||||
<!-- FOR f = fielddescs -->
|
||||
<option value="{s f.id}"<!-- IF eq(get(concat(fld,'_field')), f.id) --> selected<!-- END -->>{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
<select style="width:100px" name="{fld}_func">
|
||||
<option value="">без преобразования</option>
|
||||
<!-- FOR f = functions -->
|
||||
<option value="{s f.id}"<!-- IF eq(get(concat(fld,'_func')), f.id) --> selected<!-- END -->><!-- IF f.time -->(время) <!-- END -->{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
Loading…
Reference in New Issue