|
|
|
| помогите пож. составить запрос :
есть 4 таблицы, вот их структура:
programma {id_prog, name_prog}
например {1, программа1; 2, программа 2; 3, программа 3}
voprosy{id_vopr, name_vopr}
tema{id_tema, name_tema}
full{id, id_prog, id_tema, id_vopr}
структура таблиц такая, т.к. некоторые темы и вопросы могут перекликаться в некоторых программах
надо выбрать тему на форме и нажать кнопку перейти на форме, после чего на экране должны вывестись соответствующие ей темы и в каждой вопросы.
<?
$query2 = "SELECT * FROM programma";
$sub2 = mysql_query($query2,$db);
if(!$sub2) exit(mysql_error());
echo "<select name='sel_prog' size='1'>";
while($tmp = mysql_fetch_array($sub2))
{ echo "<option>$tmp[name_progr]</option><br>";
} echo "</select>";
?><input name="perehod" type="submit" value="перейти">
|
| |
|
|
|
|
|
|
|
для: lilu
(08.10.2007 в 12:56)
| | >, после чего на экране должны вывестись соответствующие ей темы и в каждой вопросы.
непонятно что находится в таблице full и как узнатть какие темы соответствуют выбранной программе ,
и какие вопросы соответствуют теме соответствующей выбранной программе?
например перейдёт пользователь на страницу "script.php?sel_prog=1",
по ссылке сгенерированной в форме
<?
while($tmp = mysql_fetch_array($sub2))
{
echo "<option value='$tmp[id_prog]'>$tmp[name_prog]</option>\n";
}
|
и что ему надо показать ? названия тем и вопросов с такими-же id ? если в трёх таблицах содержатся только айди и имена | |
|
|
|
|
|
|
|
для: EXP
(08.10.2007 в 17:17)
| | возможно база данных составлена не совсем грамотно, подскажите ккак лучше тогда, если например есть три программы -
прорамма для экономистов,
программа для бухгалтеров,
программа для монтёров.
Есть темы конечно специфические согласно специальности, но у всех есть и общие темы, например -"Общее положение о предприятии", "Коллективный договор", "Техника безопасности" и т.д.
Что касается вопросов, то например в теме "Техника безопасности" для экономистов не должны быть вопросы касающиеся специфики работы монтёров (такие как - работы на высоте и т.д.).
Поэтому я составила три отдельные таблицы, где просто перечисляются программы, темы и вопросы, чтобы не писать текст, я заменила их на id.
И одну общую full - где с помощью id предыдущих таблиц - собственно формируются каждая из трёх программ.
Согласно приведённого кода на экран выводится список программ для пользователя и нажав кнопку перейти, он должен увидеть название тем, согласно выбранной программе и название вопросов, согласно выбранных тем. | |
|
|
|
|
|
|
|
для: lilu
(09.10.2007 в 09:21)
| | мне и самому интересно как правильнее такое организовать :)
можно всё сделать вообще на одной таблице , только незнаю можно-ли такое делать :)
если таких программ так немного ,
можно средствами php организовать что-то типа array(0 =>'человек без профессии', 1 =>'монтёр', 2 =>'бухгалктер', 3 =>'экономист');
и обойтись двумя таблицами,
если необязательно на каждой странице напоминать монтёрам название их профессии
а просто использовать получаемый id :)
непроверял но должно работать даже и такое
<?php
$query_szdtbl1 = "CREATE TABLE voproses (
id_v int(11) NOT NULL AUTO_INCREMENT, " // порядковые номера вопросов (необязательно)
. "name_v text NOT NULL, " // название каждого (необязательно)
. "body_v text NOT NULL, " // само содержание вопроса
. "theme_id int(5) NOT NULL, " // id темы к которой относится
. "profes enum(0, 1, 2, 3) NOT NULL default 0, " // профессия читателя
. "date datetime NOT NULL default '0000-00-00 00:00:00', " // время добавления (необязательно)
. "PRIMARY KEY (id_v) " // (необязательно)
. ") TYPE=MyISAM;";
?>
ВТОРАЯ ТАБЛИЦА
<?php
$query_szdtbl2 = "CREATE TABLE t_names (
id_t int(5) NOT NULL AUTO_INCREMENT, // номера тем
name_t text NOT NULL, // названия тем
profes enum(0, 1, 2, 3) NOT NULL default 0, // профессия читателя
PRIMARY KEY (id_v)
) TYPE=MyISAM;";
?>
ВЫБРАТЬ НАЗВАНИЯ ТЕМ ДЛЯ ПРОФЕССИИ МОЖНО ТАК
<?php
$query_them = 'SELECT id_t, name_t FROM t_names (
WHERE profes = ' . (int)$_GET['sel_prog'] . ';';
## ИЛИ ВЫБРАТЬ ВОПРОСЫ ПО ТЕМАМ С НАЗВАНИЕМ ТЕМЫ ##
$query = 'SELECT id_v.voproses, name_v.voproses, body_v.voproses, date.voproses,
name_t.t_names
FROM voproses LEFT JOIN t_names
ON profes.voproses = ' . (int)$_GET['sel_prog'] . '
AND theme_id.voproses = ' . $thema = (int)$_GET['thema'] . '
AND id_t.t_names = ' . $thema . '
GROUP BY id_v.voproses;'; // наверное
// НЕУДОБНО ТЕМ ЧТО С КАЖДЫМ ВОПРОСОМ ВОЗВРАЩАЕТ СНОВА НАЗВАНИЕ ТЕМЫ
## ИЛИ ВЫБРАТЬ НАЗВАНИЯ ТЕМ И ВОПРОСОВ ##
$query = 'SELECT name_v.voproses, name_t.t_names
FROM voproses LEFT JOIN t_names
ON profes.voproses = ' . (int)$_GET['sel_prog'] . '
AND theme_id.voproses = ' . $thema = (int)$_GET['thema'] . '
AND id_t.t_names = ' . $thema . '
GROUP BY id_v.voproses;';
?>
|
я ещё не волшебник я только учусь )
хотелось-бы знать как-же такое правильно организуется
// или просто делать несколько запросов к MySQL в этих файлах
// наверное там где enum(0, 1, 2, 3) профессия 0 , не безработный , а для всех профессий,
надо только тогда поменять условие в выборке на profes.voproses = ' . (int)$_GET['sel_prog'] . ' OR profes.voproses = 0 | |
|
|
|
|
|
|
|
для: EXP
(09.10.2007 в 15:00)
| | одной таблицей имел ввиду вот.так )
<?php
$query_create_tbl = 'CREATE TABLE x_table ( '
. 'id int(11) NOT NULL AUTO_INCREMENT, '// порядковые номера рядов (необязательно)
. 'chto enum(\'proff\', \'tema\', \'vopros\') NOT NULL default "vopros", ' // что-за вообщче ряд :)
. 'context_id int(5) NOT NULL, ' // идентификационный ключ тем и проффессий
. 'otnosh tinytext NOT NULL, ' // строка с указанием идентификаторов тем к каким относится вопрос например через пробел '0 3 4'
. 'dopusk tinytext NOT NULL, ' // строка с ключами имеющих допуск к чтению вопросов и тем например через пробел '0 3 4'
. 'body text NOT NULL, ' // содержимое
. 'date datetime NOT NULL default \'0000-00-00 00:00:00\', ' // время добавления (необязательно)
. 'PRIMARY KEY (id) ' // (необязательно)
. ') TYPE=MyISAM;';
?>
ВЫБРАТЬ НАЗВАНИЯ ТЕМ ДЛЯ ПРОФЕССИИ
<?php
$query_them = 'SELECT id body FROM x_table
WHERE chto="tema"
AND LOCATE("' . (int)$_GET['sel_prog'] . '", dopusk) NOT 0;';
# ВОПРОСЫ ПО ТЕМЕ
$query_vop = 'SELECT id body FROM x_table
WHERE chto="vopros" AND LOCATE("' . (int)$_GET['thema'] . '", otnosh) NOT 0
AND LOCATE("' . (int)$_GET['sel_prog'] . '", dopusk) NOT 0;';
/* ВЫБРАТЬ ВОПРОСЫ ПО ТЕМАМ
С НАЗВАНИЕМ ТЕМЫ И НАЗВАНИЕМ ПРОФЕСИИ :)
и тоже повторяются много раз названия */
$query = "SELECT id,
CONCAT_WS('', '', (SELECT body FROM x_table
WHERE context_id =" . (int)$_GET['sel_prog'] . "
AND chto='proff')) AS proff,
CONCAT_WS('', '', (SELECT body FROM x_table
WHERE chto="tema"
AND context_id =" . (int)$_GET['thema'] . ")) AS thema
FROM x_table
WHERE chto="vopros" AND LOCATE('" . (int)$_GET['thema'] . "', otnosh) != 0
AND LOCATE('" . (int)$_GET['sel_prog'] . "', dopusk) != 0;";
?>
| даже если последний запрос будет из разных таблиц , возвращаемый результат весит на порядок больше чем нужно , поэтому
наверное проще сделать несколько запросов к базе, но говорят что их лучше когда меньше | |
|
|
|
|
|
|
|
для: EXP
(09.10.2007 в 15:00)
| | раз никто непоправляет , примерно так делается выбор из трёх таблиц без повтора одних и тех-же значений :)
CREATE TABLE mesg (
id_mesg int(7) NOT NULL AUTO_INCREMENT,
time datetime NOT NULL default '0000-00-00 00:00:00',
dop tinytext NOT NULL,
otnosh tinytext NOT NULL,
body text NOT NULL,
PRIMARY KEY (id_mesg)
) TYPE=MyISAM;
INSERT INTO mesg (time,
dop, otnosh,
body)
VALUES ( NOW(),
'0', '0',
'вопрос для всех , показывается во всех разделах'), ( NOW(),
'2 3', '2',
'вопрос для модеров и админов такой показывается только в разделе с айди 2'),
( NOW(),
'1', '1 3',
'вопрос для юзеров показывается в разделе с айди 1 и 3');
CREATE TABLE users (
id_users int(7) NOT NULL AUTO_INCREMENT,
id_dop int(2) NOT NULL default '0',
name VARCHAR(25) NOT NULL,
pswrd tinytext NOT NULL,
status enum('user', 'moder', 'admin') NOT NULL default 'user',
UNIQUE KEY (name),
PRIMARY KEY (id_users)
) TYPE=MyISAM;
INSERT INTO users (name, id_dop, pswrd, status) VALUES ('admin', 3,
MD5('admin'),
'admin'), ('moder', 2,
MD5('moder'),
'moder'), ('user', 1,
MD5('user'),
'user');
CREATE TABLE razd (
id_razd int(7) NOT NULL AUTO_INCREMENT,
id_otnosh int(5) NOT NULL default '0',
dop tinytext NOT NULL,
r_name text NOT NULL,
PRIMARY KEY (id_razd)
) TYPE=MyISAM;
INSERT INTO razd (id_otnosh, dop,
r_name)
VALUES (1, '0',
'раздел для всех'),
(2, '2 3', 'раздел для модеров и админов'),
(3, '1', 'раздел для юзеров');
<?
// ВЫБОР ВОПРОСОВ РАЗДЕЛОВ И ЮЗЕРОВ )
$status = (isset($_GET['status'])) ? (int)$_GET['status'] : 0 ;
$razd = (isset($_GET['razd'])) ? (int)$_GET['razd'] : 0 ;
$vop = (isset($_GET['vop'])) ? (int)$_GET['vop'] : 0 ;
$sql = "(SELECT id_users, name, (@dop := id_dop) AS df FROM users
WHERE status=$status )
UNION ALL
( SELECT id_razd, r_name, (@otn := id_otnosh) AS of
FROM razd
WHERE id_razd=$razd
AND ((LOCATE(@dop, dop) != 0) OR (LOCATE('0', dop) != 0)) )
UNION ALL
( SELECT id_mesg, body, 0
FROM mesg
WHERE ((LOCATE(@dop, dop) != 0) OR (LOCATE('0', dop) != 0))
AND ((LOCATE(@otn, otnosh) != 0) OR (LOCATE('0', otnosh) != 0)) LIMIT 0, 30 );" ; // íàïðèìåð :)
$result = m_query($sql);
while($line = mysql_fetch_array($result, MYSQL_ASSOC))
{
var_dump($line);
}
?>
|
только там вместо бухгалтеров модеры :)
вот и думать потом из чего лучше выбрать приходится выбирая между понятным и не очень )
насчёт работоспособности такого способа не уверен :) | |
|
|
|
|