如何使用一个序列化数据加入两列?

时间:2014-01-15 10:27:30

标签: php mysql sql codeigniter activerecord

我正在尝试建立一个对产品提供多类别支持的电子商店,因此每当我从<select>中选择特定类别时,我serialize()将它们保存到数据库中。

所以现在,我想通过尝试连接两个表来输出JOINed表,其中包含我需要的所有db数据:CATEGORIES中的ECOMMERCE_PRODUCTSapp/models/ecommerce_model.php

$this->db
    ->select('
            ecommerce_products.id,
            categories.id AS catid,
            categories.title AS categories,
            ecommerce_products.manid,
            ecommerce_products.name
        ')
    ->join('categories', 'ecommerce_products.catid = categories.id', 'left');
    ->join('categories as man', 'ecommerce_products.manid = man.id', 'left');
    $this->db->get('ecommerce_products')->result();

第一个JOIN代表产品类别,第二个JOIN代表产品制造商,它们也存储在categories表中。

所以要澄清一下,在第一个JOIN中调用的ecommerce_products.catid是序列化的,我想知道在进行JOIN之前如何反序列化它?

2 个答案:

答案 0 :(得分:3)

MySQL不知道PHP序列化是什么。您可以按以下格式将类别的ID存储为字符串:

2,4,5,10,...

然后,使用SUBSTRING_INDEX()FIND_IN_SET() MySQL函数的组合来检查categories.id中是否存在ecommerce_products.catid

SUBSTRING_INDEX(
    SUBSTRING_INDEX(ecommerce_products.catid,
        ',',
        FIND_IN_SET(categories.id, ecommerce_products.catid)
), ',', -1)

要为每个产品记录选择类别标题,我们需要通过GROUP_CONCAT()函数连接标题,因此最终查询将是这样的:

SELECT p.id,
       p.catid
       GROUP_CONCAT(cat.title ORDER BY cat.id SEPARATOR '|') as 'categories',
       p.manid,
       p.name
FROM ecommerce_products AS p
LEFT JOIN categories AS cat
    ON cat.id = SUBSTRING_INDEX(SUBSTRING_INDEX(p.catid, ',', FIND_IN_SET(cat.id, p.catid)), ',', -1)
-- more query...
GROUP BY p.id; -- Group the result to concatenate the categories titles

在此方法中,您可能需要使用$this->db->query();方法手动运行查询。

注意:
作为替代方案,您可以将以下内容用于ON语句:

LEFT JOIN categories AS cat
    ON p.catid REGEXP CONCAT('[,]{0,1}', cat.id, '[,]{0,1}')

测试用例

以下是我在 SQLFiddle 上的测试用例:

SELECT p.id,
       p.name,
       GROUP_CONCAT(c.title ORDER BY c.id SEPARATOR '|') as 'categories'
FROM products as p
JOIN categories as c
  ON c.id = SUBSTRING_INDEX(SUBSTRING_INDEX(p.cat_id, ',', FIND_IN_SET(c.id, p.cat_id)) , ',', -1)
GROUP BY p.id;

结果:

ID    NAME          CATEGORIES
--    ---------     -----------
1     Product 1     Cat 1|Cat 3
2     Product 2     Cat 2|Cat 4
3     Product 3     Cat 1|Cat 4
4     Product 4     Cat 2|Cat 3

答案 1 :(得分:1)

我认为在这种情况下,序列化ecommerce_products.catid的错误解决方案将在以后用于连接表格。未知将来会使用序列化数据以及可能出现的问题:看,你已经遇到了一个简单的连接选择问题。

所以虽然不迟,但我建议重新考虑这种方法。我认为,在此指定时刻,最佳解决方案是添加第三个表categories2ecommerce_products,其中包含两个字段:category_idecom_product_cat_id(例如)。它将通过他们的id(创建关系表)将类别与ecommerce_products连接(关联)。