|
 27.1 Кб |
|
| После левого объединения получилась таблица, дамп которой привожу.
Как мне стоит разобрать лучше разобрать массив
<?php
for ($base=array(); $row=mysql_fetch_assoc($ctg); $base[]=$row);
?>
|
чтобы получить данные в таком табличном формате
st_name | e_data - e_name - e_type |e_data1 - e_name1 - e_type1 |
Иванов | score | score |
петров | score | score | | |
|
|
|
|
|
|
|
для: куч1963
(12.04.2010 в 02:30)
| | Вы бы сам запрос привели... | |
|
|
|
|
|
|
|
для: Trianon
(12.04.2010 в 03:35)
| | То, что я прикрепил в файле есть результат от объединения этих таблиц запросом
CREATE TABLE IF NOT EXISTS `event` (
`id_event` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` text NOT NULL,
`pos` smallint(3) unsigned NOT NULL DEFAULT '0',
`hide` enum('show','hide') NOT NULL DEFAULT 'show',
`type` enum('T','L','K','Z','E') NOT NULL DEFAULT 'T',
`id_plan` smallint(6) unsigned NOT NULL,
PRIMARY KEY (`id_event`),
KEY `sort_id` (`id_plan`),
KEY `id_plan` (`id_plan`),
KEY `type` (`type`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
CREATE TABLE IF NOT EXISTS `score` (
`student_id` int(10) unsigned NOT NULL,
`id_group` tinyint(3) unsigned NOT NULL,
`id_event` int(10) unsigned NOT NULL,
`score` text NOT NULL,
`data` date NOT NULL,
`id_prepod` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_event`,`student_id`),
KEY `student_id` (`student_id`)
) ENGINE=InnoDB DEFAULT CHARSET=cp1251;
CREATE TABLE IF NOT EXISTS `students` (
`student_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`sex` enum('f','m') NOT NULL,
`id_group` tinyint(3) unsigned NOT NULL,
PRIMARY KEY (`student_id`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
|
Собственно сам запрос
SELECT
students.name AS st_name,
event.name AS e_name,
event.`type` As e_type,
score.score AS score,
score.`data` AS e_data
FROM
students
INNER JOIN event
LEFT JOIN score
ON students.student_id = score.student_id
AND event.id_event = score.id_event
WHERE
students.id_group = 11 AND
event.id_plan = 49
ORDER BY
event.pos, event.id_event ";
|
Левое соединение применено сознательно для получения полной выборки по таблице event | |
|
|
|
|
|
|
|
для: куч1963
(12.04.2010 в 07:19)
| | students
INNER JOIN event
Это как ?
полное декартово произведение? | |
|
|
|
|
|
|
|
для: Trianon
(12.04.2010 в 09:40)
| | Практически так и выходит. Мне нужно выбрать все события из таблицы event и выбрать всех из таблицы students.
Структура вывода по горизонтали:
1 строка: Ф.И.О /событие1/событие2/././включая те, которые не произошли
послед. стр. Фамилия/результат события1/результат2/ | |
|
|
|
|
|
|
|
для: куч1963
(12.04.2010 в 10:15)
| | Так может просто нужно ORDER BY добавить определенности?
ORDER BY students.name, students.students_id, event.pos, event.id_event
|
Ну и дальше цикл по всем записям.
Данные будут предоставлены сугубо в порядке формирования ячеек HTML-таблицы.
Левый заголовок строки с именем студента (и конечно закр тег предыдущей) выводить в момент смены student_id. | |
|
|
|
|
|
|
|
для: Trianon
(12.04.2010 в 11:26)
| | Так конечно лучше, только вот не доходит, как правильно сформировать первую строку.
По идее
[code]
<table>
<tr><td>F.I.O</td><td>событие 1</td><td>событие 2</td>.....</tr>
<tr><td>name</td><td>score 1</td><td>score 1</td>.....</tr>
/code]
Получается что, нужно за первый проход цикла формировать 1 строку, а затем возвращаться обратно, и уже формировать данные? | |
|
|
|
|
|
|
|
для: куч1963
(12.04.2010 в 11:50)
| | первую строку можно сформировать либо до цикла, либо, что более естественно - по флагу отсутствия заголовка.
Можно также применить предпросмотр набора результата на строку вперед, хотя по-моему это уже излишне. | |
|
|
|
|
|
|
|
для: Trianon
(12.04.2010 в 12:45)
| | Что-то я совсем с флагами запутался. Это флаг надо ставить не только на отсутствие, но и на наличие?
Туплю совсем:((.
Репа уже не соображает. Что я не так делаю, в этом коде?
$flag ="";
echo "<table>";
$i=0;
while ($row=mysql_fetch_assoc($ctg))
{
if($flag != $row['e_name'])
{
if($i ==0)
{
echo "<tr><td>ФИО</td>";
++$i;
}
echo "<td>".$row['e_name']."</td>";
$flag=$row['e_name'];
}
}
|
Как правильно поставить флаги? не могу дойти своим мозогом. | |
|
|
|
|
|
|
|
для: куч1963
(12.04.2010 в 13:33)
| | в этом коде Вы в первую очередь не так расставили отступы.
Полагаю, сделав это непреднамеренно.
Потому что преднамеренная публикация кода без отступов выглядит, как плевок. | |
|
|
|
|
|
|
|
для: Trianon
(12.04.2010 в 20:39)
| | Вы совершенно правы в том, что такая публикация кода была сделана неосознанно.
Вот, что получилось в результате творчества.
Вроде все работает, только хотелось бы прочесть ваше мнение о реализации.
<?php
//Объявляю два массива для контроля элементов
$flag = array ();
$flag1 = array ();
echo "<table border=1>";
$i = 0; //Объявляю переменную для вывода первой строки первого столба
while ($row = mysql_fetch_assoc($ctg)) {
if (!in_array($row['e_name'], $flag, true)) {
if ($i == 0) {
echo "<tr><td>ФИО</td>";
++$i;
}
echo "<td>" . $row['e_name'] . "</td>";
$flag[] = $row['e_name'];
} elseif (in_array($row['e_name'], $flag, true)) {
if (!in_array($row['student_id'], $flag1, true)) {
echo "</tr><tr><td>" . $row['st_name'] . "</td>";
$flag1[] = $row['student_id'];
}
echo "<td>";
if (empty($row['score'])) {
echo " ";
} else {
echo $row['score'];
}
echo "</td>";
}
}
echo '</table>';
?>
|
| |
|
|
|
|
|
|
|
для: куч1963
(12.04.2010 в 22:05)
| | кошмар.
Сделать флаг - фактически идентификатор текущего студента - массивом?
Такое разбазаривание ресурсов я не видел очень давно.
<?
echo "<table>\r\n";
$flag = ''; // студент не открыт
while ($row = mysql_fetch_assoc($ctg))
{
if($flag != $row['stud_id']) // ситуация нового студента
{
if($flag !== '') // при открытом старом
echo "</tr>\r\n";
$flag = $row['stud_id']
printf("<tr id=\"st_%d\"><th>"%s"</th>\r\n",
$flag, htmlspecialchars($row['stud_name']) );
}
printf(" <td>"%s"<td> <td>"%s"<td> <td>"%s"<td>\r\n",
htmlspecialchars($row['score_date']),
htmlspecialchars($row['event_name']),
htmlspecialchars($row['event_type']) );
}
if($flag !== '') //если студент остался открыт
echo "</tr>\r\n";
echo "</table>\r\n";
|
| |
|
|
|
|
|
|
|
для: Trianon
(12.04.2010 в 22:40)
| | А как мне теперь видоизменить, чтобы получить в первой строке
<?
echo "<table>\r\n";
echo "<tr><td>F I O</td><td>".htmlspecialchars($row['event_name'])."</td> \r\n";
|
и закрыть первую строку? | |
|
|
|
|
|
|
|
для: куч1963
(12.04.2010 в 23:07)
| | внесите правку в тот оператор, что под условием. | |
|
|
|
|
|
|
|
для: Trianon
(12.04.2010 в 23:31)
| | Нужно добавлять еще одно условие и флаг?
Сейчас пробую это сделать на вашем примере, не выходит.
if($flag1 != $row['id_event']) // новая строка
{
if($flag1 !== '') // при открытом старом
echo "</tr>\r\n";
$flag1 = $row['id_event'];
printf("<tr id=\"ev_%d\"><th>\"%s\"</th>\r\n", $flag1, "FIO" );
}
printf(" <td>\"%s\"</td>\r\n",htmlspecialchars($row['e_name']));
|
как закрыть его, и передать дальше | |
|
|
|
|
|
|
|
для: куч1963
(12.04.2010 в 23:57)
| | Зачем еще одно условие?
У Вас на одного студента несколько событий?
Вы приведите пример выдачи, так чтобы можно было понять сколько каких строк откуда выводится.
PS.А впрочем, лучше не приводите. | |
|
|
|
|
|
|
|
для: Trianon
(12.04.2010 в 23:59)
| | Вы наверное устали объяснять мне прописные истины, но к сожалению - трудно доходит:((
Вывод должен быть таким:
первая строка:
ФИО/событие1/событие2/.....</tr>
name/оценка1/оценка2/...</tr>
Я благодарен Вам, за то, что потратили на объяснение свое время. | |
|
|
|
|
|
|
|
для: куч1963
(13.04.2010 в 00:10)
| | а вторая?
а третья?
А второй третий студенты?
name это имя события или имя студента?
если имя события, то что такое событие1, 2 и так далее?
если имя студента, то что такое ФИО?
1, 2 это нумерация сквозная или внутри одного студента?
Вы издеваетесь.
Теперь, впрочем, я устал объяснять и этот последний тезис тоже. | |
|
|
|
|
 12.1 Кб |
|
|
для: Trianon
(13.04.2010 в 01:01)
| | Я не прав. Нарисовал, как это должно выглядеть. Событие - название темы занятия.
PS уметь объяснить, что ты хочешь, может далеко не всякий. | |
|
|
|
|
|
|
|
для: куч1963
(13.04.2010 в 02:04)
| | Да уж. В жизни бы не догадался.
Знаете, что Вы не сделали?
Вы не обвели жирным шапку Вашей таблицы. Не показали, что это отдельный поток данных.
Нет ничего зазорного в том, чтобы вытащить данные шапки отдельным - более простым запросом.
Уж коль скоро Вам все равно нужно все события показывать, а не только те, по которым оценки имеются.
И там не нужна будет возня с флагами.
PS. Хотеть больше, чем умеешь выразить - хотеть лишнего. | |
|
|
|
|
|
|
|
для: Trianon
(13.04.2010 в 09:23)
| | Я всегда внимательно разбираю ваши советы и приведенные решения.
В том коде, что Вы привели, есть всё необходимое для решения моей задачи.
Правда флаг пришлось поставить, и собрать в одну переменную первую строку, все остальное в другую.
Получилось так.
<?
$flag = ''; // студент не открыт
$roll_st="";
$zag_td ="";
$break_1_row=0;
while ($row = mysql_fetch_assoc($ctg))
{
if($flag != $row['student_id']) // ситуация нового студента
{
if($flag !== ''){ // при открытом старом
$zag_td .="</tr>\r\n";
$roll_st .= "</tr>\r\n";
$break_1_row=1;
}
$flag = $row['student_id'];
if($break_1_row==0){
$zag_td .= sprintf("<tr><th>\"%s\"</th>\r\n", "FIO" );
}
$roll_st .= sprintf("<tr id=\"st_%d\"><th>\"%s\"</th>\r\n",
$flag, htmlspecialchars($row['st_name']) );
}
if($break_1_row==0){
$zag_td .= sprintf(" <td>\"%s\"</td>\r\n",$row['e_name'] );
}
$roll_st .= sprintf(" <td>\"%s\"</td>\r\n", $row['score']);
}
echo $zag_td;
echo $roll_st;
if($flag !== '') //если студент остался открыт
echo "</tr>\r\n";
echo "</table>\r\n";
|
Наверняка, снова есть косяки, но все выводит как надо. Огромное спасибо за разъяснения и помощь в решении этой задачи. Даже в принципе, если учитывать тот факт, что в html не предъявляется особых требований к закрывающим /tr, то можно еще дальше модифицировать:))
PS К сожалению, при общении с людьми, мы мало уделяем внимания тому факту, что логика мышления у людей разная. | |
|
|
|
|
|
|
|
для: куч1963
(13.04.2010 в 10:24)
| | так, в принципе, тоже можно.
Попробуем разобрать плюсы и минусы.
плюсы: один запрос вместо двух
минусы: Сильно осложненная логика алгоритма, запутанный код, и самое главное - необходимость накапливать выходной поток в переменных.. А значит - изрядные требования к скрипту по памяти.
Впрочем, еще один плюс -- этот вариант Вы самостоятельно не только реализовали, но и придумали.
PS. Основная цель моей деятельности на этом портале - делиться логикой мышления с другими людьми. Вернее даже - менять эту логику.
PPS. Я оценил, насколько аккуратно Вы отвечаете. | |
|
|
|
|
|
|
|
для: Trianon
(13.04.2010 в 10:38)
| | И еще один вопрос в эту тему.
Почему в запросе, если писать
FROM
students
INNER JOIN event
|
То запрос проходит, а если
То выдается ошибка. Ведь по сути эти записи эквивалентны? | |
|
|
|
|
|
|
|
для: куч1963
(13.04.2010 в 11:15)
| | JOIN может иметь условие ON
а CROSS JOIN ( или запятая) - не может. По сути смысла. | |
|
|
|