Буду очень признателен за любую помощь в этом.
Я запускаю два mysql_query
для получения массива общих бюллетеней для указанного пользователя в базе данных из одной таблицы (bulletins
) и подписанных бюллетеней из второй таблицы (bulletins_sign_log
).
Проблема, с которой я сталкиваюсь, заключается в том, как определить из двух массивов, какие бюллетени все еще требуют подписи от пользователя.
Вот примеры массивов и моих попыток:
всего бюллетеней mysql_query
PHP код
$query = mysql_query("SELECT b.id AS bulletin_id FROM bulletins b WHERE
(b.to_user_id='username' OR b.to_group_id='0')");
while($total_bulletins[] = mysql_fetch_assoc($query));
всего бюллетеней print_r
результат
Array
(
[0] => Array
(
[bulletin_id] => 1
)
[1] => Array
(
[bulletin_id] => 3
)
[2] =>
)
1
подписанные бюллетени mysql_query
PHP код
$query = mysql_query("SELECT s.bulletin_id FROM bulletins_sign_log s WHERE
s.username_id='username'");
while($signed_bulletins[] = mysql_fetch_assoc($query));
подписанные бюллетени print_r
результат
Array
(
[0] => Array
(
[bulletin_id] => 1
)
[1] =>
)
1
Здесь я не могу понять, как определить, что бюллетень # 3 из всего бюллетеней не был подписан пользователем. Я пытался использовать array_diff()
, но не получил ожидаемого результата.
сравнение array_diff
PHP код
$unsigned = array_diff($total_bulletins, $signed_bulletins);
сравнение print_r
результат
Array
(
)
1
Моя конечная цель - взять значение без знака bulletin_id
(в данном случае бюллетень № 3) и поместить его в перенаправление заголовка, если оно больше 0, например:
if($unsigned['0'] > 0){
header('location: /sign_bulletin.php?bulletin_id='.$unsigned['0'].');
}
окончательный результат
header('location: /sign_bulletin.php?bulletin_id=1');
окончательный (ожидаемый) результат
header('location: /sign_bulletin.php?bulletin_id=3');
EDIT Добавление некоторой дополнительной информации после попытки использования предложенного @ gilden SQL-запроса.
SQL-запрос , который я использовал в phpMyAdmin
SELECT b.id
FROM bulletins2 b
LEFT OUTER JOIN bulletins_sign_log2 s ON b.id = s.bulletin_id
AND b.to_user_id = s.username_id
WHERE s.bulletin_id IS NULL
AND b.to_user_id = 'username1'
OR b.to_group_id = '0'
MySQL результат от phpMyAdmin
bulletin_id
1
3
Проблема с результатом состоит в том, что он перечисляет bulletin_id # 1 как не подписанный для username1 . Однако в приведенной ниже таблице bulletins_sign_log
у username1 есть запись со знаком для этого bulletin_id. Это помечено из-за соответствующего оператора SQL:
OR b.to_group_id = '0'
to_group_id не записано в таблице bulletins_sign_log , поскольку «группа» не может что-то подписывать, но ее участники могут. Он регистрируется только в таблице bulletins
, чтобы знать, каким пользователям также отправлять бюллетень. В этом случае to_group_id '0' - это группа "Все", где все пользователи получают бюллетень.
Поэтому моей следующей мыслью было просто удалить OR b.to_group_id = '0'
, но затем я получил пустой набор. Любые идеи о том, куда идти с текущей конфигурацией базы данных? Смена БД означала бы, к сожалению, изменение МНОГО кода, тогда, возможно, часы или дни отладки.
Можно ли вернуться к первоначальной идее об отдельных массивах и каким-то образом получить их оба в массив, где могут быть удалены повторяющиеся значения? Оригинальный метод, кажется, рабочий метод для получения точной исходной информации, которая является началом. Это тогда оставило бы массив уникальных bulletin_id, которые не были подписаны.
Структура таблицы для bulletins
CREATE TABLE bulletins (
`id` int(20) NOT NULL auto_increment,
`bulletin` longtext NOT NULL,
`from_user_id` varchar(50) NOT NULL,
`to_user_id` varchar(50) NOT NULL,
`to_group_id` int(20) NOT NULL,
`subject` varchar(255) NOT NULL,
`date_sent` date NOT NULL,
`time_sent` time NOT NULL,
PRIMARY KEY (`id`),
KEY `from_user_id` (`from_user_id`),
KEY `to_user_id` (`to_user_id`),
KEY `to_group_id` (`to_group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `bulletins` VALUES(1, 'Subject 1', 'username1', 'username9', 0, 'Text Content 1', '2009-03-15', '20:31:50');
INSERT INTO `bulletins` VALUES(2, 'Subject 2', 'username1', 'username3', 9, 'Text Content 2', '2010-08-17', '12:00:00');
INSERT INTO `bulletins` VALUES(3, 'Subject 3', 'username3', 'username9', 0, 'Text Content 3', '2010-10-13', '16:45:23');
Структура таблицы для bulletins_sign_log
CREATE TABLE `bulletins_sign_log` (
`id` int(20) NOT NULL auto_increment,
`bulletin_id` int(20) NOT NULL,
`username_id` varchar(50) NOT NULL,
`accept_initials` varchar(3) NOT NULL,
`accept_date` date NOT NULL,
`accept_time` time NOT NULL,
`first_date_read` date NOT NULL,
`first_time_read` time NOT NULL,
`last_date_read` date NOT NULL,
`last_time_read` time NOT NULL,
PRIMARY KEY (`id`),
KEY `username_id` (`username_id`),
KEY `bulletin_id` (`bulletin_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `bulletins_sign_log` VALUES(1, 1, 'username1', 'AB', '2009-03-16', '12:45:10', '2009-03-16', '12:43:09', '2009-03-17', '13:05:11');
INSERT INTO `bulletins_sign_log` VALUES(2, 2, 'username5', 'CD', '2010-08-19', '00:28:07', '0000-00-00', '00:00:00', '0000-00-00', '00:00:00');
Заранее благодарим за любую помощь, которую вы можете оказать!
ФИНАЛЬНЫЙ код с помощью @ gilden - Спасибо!
Исходному отправителю не имело смысла подписывать свой собственный бюллетень, поэтому я заблокировал это как требование в запросе SQL, добавив:
AND b.from_user_id != 'username1'
ПРЕДУПРЕЖДЕНИЕ Обязательно добавьте это в конец запроса, иначе он не будет работать - поверьте мне.
... и вот последний SQL-запрос:
SELECT b.id AS bulletin_id
FROM bulletins b
LEFT OUTER JOIN bulletins_sign_log s ON b.id = s.bulletin_id
AND b.to_user_id = s.username_id
WHERE s.bulletin_id IS NULL
AND b.to_user_id = 'username1'
OR b.to_group_id = '0'
AND b.from_user_id != 'username1'
... и код PHP
$sql = "SELECT b.id AS bulletin_id FROM bulletins b
LEFT OUTER JOIN bulletins_sign_log s ON b.id = s.bulletin_id
AND b.to_user_id = s.username_id WHERE s.bulletin_id IS NULL
AND b.to_user_id = '$username' OR b.to_group_id = '0'
AND b.from_user_id != '$username'";
$query = mysql_query($sql);
$unsigned = mysql_fetch_array($query);
$value = $unsigned['0'];
if($value > 0){
header('location: /bulletin_notice.php?bulletin_id='.$value.'');
}
else{
$value = 0;
exit();
}