非常感谢对此的任何帮助。
我正在运行两个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()
但没有得到预期的结果。
PHP 代码array_diff
比较
$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');
编辑 在尝试@gilden建议的 SQL 查询后添加一些其他信息。
我在phpMyAdmin中使用的SQL查询
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'
来自phpMyAdmin的MySQL结果
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();
}
为什么不使用JOIN
来获取未签名的公告?
SELECT b.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'
这应该检索bulletins
中不在 bulletins_signed
中的所有行。如果已签名公告和未签名公告具有完全相同的字段,则应将它们存储在单个表中。附加字段将存储公告是否已签名或未嵌入。