SQL语句,连接4个表和foreach循环


SQL statement with joining 4 tables and foreach loops

你好,来自保加利亚,这是我在这里的第一篇帖子,如果我没有很好地解释一切,请原谅

我正在为在线语言课程做网站(PHP,MYSQL)的管理面板。我得看看:

  1. 包含在网站中注册的所有用户的列表
  2. 如果他们有报酬或没有报酬,其中一门课程(在moment)
  3. 如果他们已经输入了任何课程的促销代码

表名和重要表列的名称为:

  1. USERS:user_id,电子邮件,real_name
  2. PAID_COURSES:PAID_course_id,PAID_couse_name
  3. USER_PAID_XREF:XREF_id,USER_id,PAID_course_id
  4. 凭证:凭证id,用户id,凭证,支付课程id

我认为最终的结果一定是一个数组看起来像:

    array(2)
    { 
    [1]=> array(5) { 
    ["user_id"]=> string(1) "1", 
    ["email"]=> string(15) "email@email.com", 
    ["real_name"]=> string(5) "ANJEL" ,
    ["paid_course_id"]=> array(4) {
    [1]=> string(1) "1" 
    [2]=> string(1) "0" 
    [3]=> string(1) "1" 
    [4]=> string(1) "0"
    },
    ["voucher"]=> array(4) {
    [1]=> string(20) "VOUCHER-11111111111"
    [2]=> string(1) "0"
    [3]=> string(19) "VOUCHER-AAAAAAAAAAA"
    [4]=> string(1) "0"
    }
     }
    [2]=> array(5) { 
    ["user_id"]=> string(1) "2" 
    ["email"]=> string(16) "office@email.com" 
    ["real_name"]=> string(5) "MITKO" 
    ["paid_course_id"]=> array(4) {
    [1]=> string(1) "0" 
    [2]=> string(1) "1" 
    [3]=> string(1) "1" 
    [4]=> string(1) "0"
    },
   ["voucher"]=> array(4) {
    [1]=> string(1) "0"
    [2]=> string(20) "VOUCHER-22222222222"
    [3]=> string(19) "VOUCHER-BBBBBBBBBBB"
    [4]=> string(1) "0"
    }
     }
     }
  1. [1]=>是user_id的密钥
  2. 在数组中有2个额外的数组,其长度与付费课程的数量完全相同(例如,在moment只有4个付费课程-英语、西班牙语等)
  3. ["paid_course_id"][1]=>这里的键[1]是paid_couse_id
  4. ["paid_course_id"][2]=>string(1)"1"-此处的值"1"为:如果表中有一行,则当前paid_couse_id的user_paid_xref(在示例中paid_cource_id=2)的值为1如果没有行,则该值为0(换句话说,用户已经支付了本课程的费用,或者用户没有支付本课程的报酬)
  5. ["代金券"][3]=>字符串(19)"voucher-BBBBBBBBBB"-此处与数组元素键的paid_course_id相同
  6. ["凭单"][3]=>string(19)"voucher-BBBBBBBBBB"-此处的值来自表VOUCHERS列的名称-凭单

就这样,我希望有人能理解。提前感谢

您可以使用左联接来获得多张代金券和多门课程

SELECT * FROM `USERS` u
LEFT JOIN `VOUCHERS` v ON (u.user_id = v.user_id)
LEFT JOIN `USER_PAID_XREF` upx ON (u.user_id = upx.user_id)
LEFT JOIN `PAID_COURSES` pc ON (upx.paid_course_id = pc.paid_course_id)
SELECT u.user_id, u.email, u.real_name,
       GROUP_CONCAT(CONCAT(upx.paid_course_id IS NOT NULL, '|' IFNULL(v.voucher, '0'))) course_vouchers
FROM `USERS` u
LEFT JOIN `USER_PAID_XREF` upx ON (u.user_id = upx.user_id)
LEFT JOIN `VOUCHERS` v ON (u.user_id = v.user_id AND upx.paid_course_id = v.paid_course_id)
GROUP BY u.user_id

这将为每个用户生成一行,在course_vouchers中使用逗号分隔的列表。该列表的元素是管道分隔的course_id标志和voucher

我将PAID_COURSES排除在查询之外,因为您的结果似乎没有使用该表中的任何内容。

PHP将类似于:

$result = array();
while ($row = $stmt->fetch_assoc()) {
    // Split apart the pieces of $row['course_vouchers']
    $courses = array_map(function($x) { return explode('|', $x); },
                         explode(',', $row['course_vouchers']));
    $row['paid_course_id'] = array_map(function($x) { return $x[0]; }, $courses);
    $row['voucher'] = array_map(function($x) { return $x[1]; }, $courses);
    unset($row['course_vouchers']);
    $result[] = $row;
}

请注意,GROUP_CONCAT的默认大小限制为1024个字符。对于像你这样的数据,如果他们有所有课程的代金券,那么看起来大约有40门课程。如果用户可能有更多的课程,您可能需要提高此限制。请参阅此问题了解如何执行此操作。