Вход на сайт
Делаю тестовое задание
NEW 25.09.14 19:46
Задание PHP+MySQL[править]
Табличка с данными. Там всего несколько полей и несколько строк. По parent_id есть привязка к id, т.е. родитель - последователь. У каждой строчки есть значение value. Вот хотелось бы на выходе получить табличку вида
Name (имя в поле name) -
value (сумма текущего значения + сумма всех последователей по parent_id)
Важно! Используйте PHP5.5 - mysqli вместо устаревшего mysql
Таблица:
/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=*/;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*Table structure for table `table1` */
DROP TABLE IF EXISTS `table1`;
CREATE TABLE `table1` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`parent_id` int(11) DEFAULT '0',
`name` varchar(255) DEFAULT NULL,
`value` int(11) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=latin1;
/*Data for the table `table1` */
insert into `table1`(`id`,`parent_id`,`name`,`value`) values (1,0,'test1',0),(2,0,'test2',30),(3,1,'test3',31),(4,6,'test4',77),(5,3,'test5',45),(6,2,'test6',20),(7,5,'test7',10);
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
Результат[править]
Должно получиться нечто такое:
id parent_id name value sum
1 0 test1 0 86
2 0 test2 30 127
3 1 test3 31 86
4 6 test4 77 77
5 3 test5 45 55
6 2 test6 20 97
7 5 test7 10 10
Табличка с данными. Там всего несколько полей и несколько строк. По parent_id есть привязка к id, т.е. родитель - последователь. У каждой строчки есть значение value. Вот хотелось бы на выходе получить табличку вида
Name (имя в поле name) -
value (сумма текущего значения + сумма всех последователей по parent_id)
Важно! Используйте PHP5.5 - mysqli вместо устаревшего mysql
Таблица:
/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=*/;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*Table structure for table `table1` */
DROP TABLE IF EXISTS `table1`;
CREATE TABLE `table1` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`parent_id` int(11) DEFAULT '0',
`name` varchar(255) DEFAULT NULL,
`value` int(11) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=latin1;
/*Data for the table `table1` */
insert into `table1`(`id`,`parent_id`,`name`,`value`) values (1,0,'test1',0),(2,0,'test2',30),(3,1,'test3',31),(4,6,'test4',77),(5,3,'test5',45),(6,2,'test6',20),(7,5,'test7',10);
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
Результат[править]
Должно получиться нечто такое:
id parent_id name value sum
1 0 test1 0 86
2 0 test2 30 127
3 1 test3 31 86
4 6 test4 77 77
5 3 test5 45 55
6 2 test6 20 97
7 5 test7 10 10
Половина евро в час
NEW 25.09.14 22:20
в ответ miltorg 25.09.14 21:55
так его не искать, нужно, а реализовать :)
вот держи, с минимальной оптимизацией. допилишь, если нужно:
вот держи, с минимальной оптимизацией. допилишь, если нужно:
public function actionTest()
{
//вот тут сделаешь чтение посредством mysqli, как тебе нужно в задании
//я для теста посредством yii загнал все записи в массив ассоциативных массивов
$cmd = Yii::app()->db->createCommand("select * from table1");
$items = $cmd->queryAll(true);
$helper = new SumCalculator($items);
foreach($items as $item)
{
echo "{$item['id']}\t{$item['parent_id']}\t{$item['name']}\t{$item['value']}\t";
echo $helper->calc($item['id']) . "
\n";
}
}
ну и сам расчёт с минимальной оптимизацией
class SumCalculator
{
private $sums = [];
private $key2val = [];//словарь (ключ => значение)
private $children = []; //словарь (ключ => [child1, child2, ...])
function SumCalculator($items)
{
foreach($items as $item)
{
$this->key2val[$item['id']] = $item['value'];
if($item['parent_id'] != 0)
{
$this->children[$item['parent_id']][] = $item['id'];
}
}
}
public function calc($id)
{
if(!isset($this->sums[$id]))
{
$sum = $this->key2val[$id];
if(isset($this->children[$id]))
{
foreach($this->children[$id] as $child_id)
{
$sum += $this->calc($child_id);
}
}
$this->sums[$id] = $sum;
}
return $this->sums[$id];
}
}
NEW 26.09.14 01:16
Сам придумал:
$res = $mysqli->query("SELECT * FROM `table1`");
while ($row = $res->fetch_assoc()) {
$sum[$row['id']][1] = $row['value'];
$otvet[$row['id']]= $row['value'];
}
$plus=1;
while ($i++<10){
if ($plus==1){
$plus=0;
$res->data_seek(0);
while ($row = $res->fetch_assoc()) {
if ($row['parent_id'] == 0) continue;
if ($sum[$row['id']][$i]){
$sum[$row['parent_id']][$i+1]=$sum[$row['id']][$i];
$otvet[$row['parent_id']]= $otvet[$row['parent_id']]+$sum[$row['id']][$i];
$plus=1;
}
}
}
}
Рабочий пример:
http://fx-signal.ru/u.php
$res = $mysqli->query("SELECT * FROM `table1`");
while ($row = $res->fetch_assoc()) {
$sum[$row['id']][1] = $row['value'];
$otvet[$row['id']]= $row['value'];
}
$plus=1;
while ($i++<10){
if ($plus==1){
$plus=0;
$res->data_seek(0);
while ($row = $res->fetch_assoc()) {
if ($row['parent_id'] == 0) continue;
if ($sum[$row['id']][$i]){
$sum[$row['parent_id']][$i+1]=$sum[$row['id']][$i];
$otvet[$row['parent_id']]= $otvet[$row['parent_id']]+$sum[$row['id']][$i];
$plus=1;
}
}
}
}
Рабочий пример:
http://fx-signal.ru/u.php
Половина евро в час
NEW 26.09.14 12:06
1) Избегай магических чисел(я про 10)
2) Алгоритм расчёта неверен. Можешь убедиться на следующих тестовых данных:
В ответ на:
Сам придумал:
Сам придумал:
1) Избегай магических чисел(я про 10)
2) Алгоритм расчёта неверен. Можешь убедиться на следующих тестовых данных:
INSERT INTO `table1` VALUES (1,0,'test1',0),(2,0,'test2',30),(3,1,'test3',31),(4,6,'test4',77),(5,3,'test5',45),(6,2,'test6',20),(7,6,'test7',10);
Добавил:
3) Форматируй код. Иначе его даже смотреть никто не будет. Это чистое неуважение, как к возможному работодателю(простительно), так и читателям форума(расстрельная статья :) ).
4) Даже в тестовом задании, комментарии никто не отменял.
NEW 26.09.14 13:28
в ответ Posmotrim 26.09.14 12:06
Для вашей таблицы:
$res = $mysqli->query("SELECT * FROM `table2`");
while ($row = $res->fetch_assoc()) {
$sum[$row['id']][1] = $row['value'];
$otvet[$row['id']]= $row['value'];
}
$plus=1;
while ($i++<10){
if ($plus==1){
$plus=0;
$res->data_seek(0);
while ($row = $res->fetch_assoc()) {
if ($row['parent_id'] == 0) continue;
if ($sum[$row['id']][$i]){
$sum[$row['parent_id']][$i+1]+=$sum[$row['id']][$i];// <-- Тут добавил +
$otvet[$row['parent_id']]+=$sum[$row['id']][$i];
$plus=1;
}
}
}
}
Результат:
http://fx-signal.ru/u1.php
$res = $mysqli->query("SELECT * FROM `table2`");
while ($row = $res->fetch_assoc()) {
$sum[$row['id']][1] = $row['value'];
$otvet[$row['id']]= $row['value'];
}
$plus=1;
while ($i++<10){
if ($plus==1){
$plus=0;
$res->data_seek(0);
while ($row = $res->fetch_assoc()) {
if ($row['parent_id'] == 0) continue;
if ($sum[$row['id']][$i]){
$sum[$row['parent_id']][$i+1]+=$sum[$row['id']][$i];// <-- Тут добавил +
$otvet[$row['parent_id']]+=$sum[$row['id']][$i];
$plus=1;
}
}
}
}
Результат:
http://fx-signal.ru/u1.php
Половина евро в час


