Я пытаюсь научить себя PHP / mysql, создав клон целей Джо , если хотите.
Обычно у каждого пользователя есть несколько целей, и каждый день они записывают, сколько раз происходило определенное событие. Например, скажем, моя цель - пить только 1 чашку кофе в день. Если бы у меня было 3 сегодня (упс!), Я бы записал 3 «проверки» на сегодня. Я использую таблицу под названием «чеки» для хранения количества чеков на каждый день.
У меня есть следующие таблицы и образцы вставок:
CREATE TABLE `users` (
`user_id` int(5) NOT NULL AUTO_INCREMENT,
`user_email` varchar(50) NOT NULL,
`user_name` varchar(25) NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
-- Dumping data for table `users`
INSERT INTO `users` VALUES (1, 'xxx@xxx.com', 'xxx');
INSERT INTO `users` VALUES (2, 'some@guy.com', 'SomeGuy');
CREATE TABLE `goal_settings` (
`goal_id` int(5) NOT NULL AUTO_INCREMENT,
`user_id` int(5) NOT NULL,
`goal_description` varchar(100) NOT NULL,
PRIMARY KEY (`goal_id`),
KEY `user_id` (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-- Dumping data for table `goal_settings`
INSERT INTO `goal_settings` VALUES (1, 1, 'Run 1k');
INSERT INTO `goal_settings` VALUES (2, 1, 'Read 20 pages');
INSERT INTO `goal_settings` VALUES (3, 2, 'Cups of Coffee');
CREATE TABLE `checks` (
`check_id` int(40) NOT NULL AUTO_INCREMENT,
`goal_id` int(5) NOT NULL,
`check_date` date NOT NULL,
`check_count` int(3) NOT NULL,
PRIMARY KEY (`check_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-- Dumping data for table `checks`
INSERT INTO `checks` VALUES (6, 1, '2012-03-02', 3);
INSERT INTO `checks` VALUES (2, 1, '2012-03-01', 2);
INSERT INTO `checks` VALUES (3, 2, '2012-03-01', 1);
INSERT INTO `checks` VALUES (5, 1, '2012-02-29', 1);
В выводе, который я хотел бы, есть goal_ids в виде строк и диапазон дат в виде столбцов (например, календарь просмотра недели).
goal_id | 2012-03-01 | 2012-03-02 | 2012-03-03 | ... 2012-03-08 |
--------------------------------------------------------------------
1 2 3 0 ... 0
2 1 0 0 ... 0
Обратите внимание, что, если в данный день не существует проверок для данной цели, возвращается 0 вместо NULL.
Мне удалось заставить его работать плохо, используя PHP. Усеченный код, но я надеюсь, что он в основном показывает то, что я пробовал: [$ goal_ids - это массив, содержащий все цели, связанные с пользователем. $ num_days - это количество дней (то есть столбцов), которые будут отображаться, а $ goal_days - это массив, используемый для хранения дней, для которых мы ищем информацию].
$mysqli = new mysqli('xxx','xxx','xxx','goals');
$stmt = $mysqli->stmt_init();
$stmt = $mysqli->prepare("SELECT checks.check_count AS check_count
FROM `checks` WHERE goal_id = ? AND check_date = ?");
for($i=0; $i<=$goal_count - 1; $i++){
echo '<tr id="'.$goalid.'">';
for($j=0; $j <=$num_days; $j++){
$checkdate = $goal_days[$j];
$goalid = (integer) $goal_ids[$i];
if (!$stmt->bind_param("ii", $goalid, $checkdate)) {
echo "Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error;
}
if (!$stmt->execute()) {
echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}
$stmt->bind_result($check_count);
if($stmt->fetch()){
echo "<td>".$check_count."</td>";
}
else{
echo '<td>0</td>';
}
}
echo "</tr>";
}
echo "</table>";
$stmt->close();
Это, очевидно, неэффективно, потому что для m целей и n дней он делает m x n выбранных операторов.
Из чтения кажется, что я в основном пытаюсь сделать сводную таблицу, но я читал, что они также неэффективны, и я предполагаю, что то, что я делаю, лучше обрабатывается PHP, чем сводная таблица?
Это оставляет меня с объединениями, о чем, я думаю, я прошу помощи. Я рассмотрел создание новой колонки на каждый день, но я думаю, что это не идеально. Я открыт для полного изменения схемы, если это необходимо.
Надеюсь, я достаточно ясно. Любая помощь или указатели в правильном направлении будет принята с благодарностью.
Спасибо!