简体   繁体   English

将两套MySQL多维数组的PHP mysql_fetch_assoc集合并为一个一维数组

[英]Combine two PHP mysql_fetch_assoc sets of MySQL multidimensional arrays into one single-dimensional array

Would greatly appreciate any help with this. 将不胜感激与此有关的任何帮助。

I'm running two mysql_query 's to retrieve an array of total bulletins for a specified user in a database from one table ( bulletins ) and signed bulletins from a second table ( bulletins_sign_log ). 我正在运行两个mysql_query ,以从一个表( bulletins )检索数据库中指定用户的总公告数组,并从第二个表( bulletins_sign_log )检索签名的公告

The problem I'm running into is how to determine out of the two arrays, which bulletins still require signature from a user. 我遇到的问题是如何从两个数组中确定,哪些公告仍需要用户签名。

Here's the example arrays and my attempts so far: 这是到目前为止的示例数组和我的尝试:

total bulletins mysql_query PHP code 公告总数 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));

total bulletins print_r result 公告总数 print_r结果

Array
(
    [0] => Array
        (
            [bulletin_id] => 1
        )

    [1] => Array
        (
            [bulletin_id] => 3
        )

    [2] => 
)
1

signed bulletins mysql_query PHP code 签名公告 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));

signed bulletins print_r result 签名的公告 print_r结果

Array
(
    [0] => Array
        (
            [bulletin_id] => 1
        )

    [1] => 
)
1

This is where I can't figure out how to determine that bulletin # 3 from total bulletins hasn't been signed by the user. 这是我无法确定如何从总公告中确定第3号 公告尚未由用户签名的地方。 I've tried using array_diff() but didn't get the expected result. 我尝试使用array_diff() ,但未获得预期结果。

comparison array_diff PHP code 比较 array_diff PHP代码

$unsigned = array_diff($total_bulletins, $signed_bulletins);    

comparison print_r result 比较 print_r结果

Array
(
)
1

My ultimate goal is to take the value of the unsigned bulletin_id (bulletin #3 in this case) and place it into a header redirect if greater than 0 such as: 我的最终目标是获取未签名的bulletin_id的值(在这种情况下为bulletin#3),如果大于0,则将其放入标头重定向中,例如:

if($unsigned['0'] > 0){
    header('location: /sign_bulletin.php?bulletin_id='.$unsigned['0'].');
}

final result 最后结果

header('location: /sign_bulletin.php?bulletin_id=1');

final (expected) result 最终(预期)结果

header('location: /sign_bulletin.php?bulletin_id=3');


EDIT Adding some additional information after trying @gilden's suggested SQL query. 编辑尝试@gilden建议的SQL查询后添加一些其他信息。

SQL query that I used in phpMyAdmin 我在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'

MySQL result from phpMyAdmin 来自phpMyAdmin的MySQL结果

bulletin_id
          1
          3

The problem with the result is that it lists bulletin_id #1 as not being signed for username1 . 结果的问题在于,它列出的bulbulin_id#1没有为username1签名。 However, in the example bulletins_sign_log table below, username1 has a "signed" record for this bulletin_id. 但是,在下面的示例bulletins_sign_log表中, username1具有此bulletin_id的“已签名”记录。 It's being flagged because of the matching SQL statement: 由于匹配的SQL语句而被标记:

OR  b.to_group_id = '0'

to_group_id is not recorded in the bulletins_sign_log table as a "group" cannot sign for something but it's members can. to_group_id未记录在bulletins_sign_log表中,因为“组”不能签名,但是它的成员可以签名。 It is only logged in the bulletins table to know which users to send the bulletin too. 仅将其记录在bulletins表中才能知道哪些用户也要发送公告。 In this case, to_group_id '0' is the "Everyone" group where all users receive the bulletin. 在这种情况下, to_group_id'0'是“所有人”组,所有用户均在其中接收公告。

So my next thought was to just remove OR b.to_group_id = '0' but then I get an empty set. 因此,我的下一个想法是仅删除OR b.to_group_id = '0'但随后得到一个空集。 Any ideas on where to go from here with the current database configuration? 关于当前数据库配置从何而来的任何想法? Changing the DB would mean changing A LOT of code unfortunately then hours or days of debugging possibly. 不幸的是,更改数据库将意味着更改大量代码,然后可能需要数小时或数天的调试时间。

Would it be possible to go back to the original idea of separate arrays and somehow get them both into an array where duplicate values can be removed? 是否可以回到分离数组的原始思想,并以某种方式将它们都放入可以删除重复值的数组中? The original method seems to be a working method for getting accurate source information which is a start. 原始方法似乎是一种获取准确源信息的可行方法,这是一个开始。 This would then leave an array of unique bulletin_id's that have not been signed. 然后,这将留下未签名的唯一的bulletin_id数组。

Table structure for bulletins 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');

Table structure for bulletins_sign_log 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');

Thank you in advance for any help you can provide! 预先感谢您提供的任何帮助!


FINAL code with @gilden 's help - Thanks! @gilden的帮助下完成代码 -谢谢!

It didn't make sense for the original sender to have to sign his own bulletin so I blocked that as a requirement from the SQL query by adding: 原始发件人必须签署自己的公告没有任何意义,因此我通过添加以下内容阻止了SQL查询的这一要求:

AND b.from_user_id != 'username1'

WARNING Be sure to add that to the bottom of the query or it won't work - trust me. 警告请确保将其添加到查询的底部,否则将无法正常工作-相信我。

...and here's the final SQL query: ...这是最终的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'

...and the PHP code ...以及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();
}

Why not use JOIN to get the unsigned bulletins? 为什么不使用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'

This should retrieve all the rows in bulletins that are not in bulletins_signed . 这应该检索bulletins中未在bulletins_signed所有行。 If both the signed and unsigned bulletins have exactly the same fields, you should store them in a single table. 如果已签名和未签名的公告都具有完全相同的字段,则应将它们存储在单个表中。 An additional field would store if a bulletin is signed or not insetad. 如果公告已签名或未设置,则会存储一个附加字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM