MYSQL JOIN条件检查以逗号分隔列表的整数

时间:2013-08-01 12:20:54

标签: php mysql inner-join sqldatatypes

我有一个SQL SELECT语句,其中我使用了3个表。 我正在使用INNER JOIN来连接表,但是我遇到了一个问题,因为我希望连接条件基于的两个列是不同的数据类型; 一个是整数 - products表的id,可以在下面看作p.id. 另一个是订单表中这些id的逗号分隔字符串。客户可以一次订购多个产品,因此产品ID存储为逗号分隔列表。

这是我对SQL的了解:

"SELECT o.transaction_id, o.payment_status, o.payment_amount, o.product_id, o.currency, o.payment_method, o.payment_time, u.first_name, u.last_name, u.email, p.title, p.description, p.price
FROM orders AS o
INNER JOIN products AS p ON ( NEED HELP HERE--> p.id IN o.product_id comma delimited list)
INNER JOIN users AS u ON ( o.user_id = u.id ) 
WHERE user_id =  '39'
ORDER BY payment_time DESC 
LIMIT 1";

也许我可以使用REGEX?目前以逗号分隔的列表显示为“2,1,3” - 但字符数不受限制 - 所以我需要一个条件来检查我的产品ID(p.id)是否在o.product_id列表中?

2 个答案:

答案 0 :(得分:0)

您拥有的是一对多关系的完美示例,其中您有一个订单和几个附加的项目。你应该有一个像

这样的链接表

order_product - 在orderid和productid之间建立连接,你也可以为两者之间的关系设置特定数据(比如添加项目时,数量等)

然后使用此表进行连接,并且到处都有相同的字段类型。

简单的例子:

select 
    /* list of products */
from
    order o,
    order_product op,
    product p
where 
    o.id = 20
and o.id = op.orderid
and op.productid = p.id

答案 1 :(得分:0)

这是使用旧数据库时的一个常见噩梦。

规则很简单:永远不要在一个表列中存储多个值。这称为first normal form

但如何在现有数据库中处理?

好事™

如果您有机会重构数据库,请将“逗号分隔值”提取到自己的表中。有关如何执行此操作的基本示例,请参阅http://sqlfiddle.com/#!2/0f547/1

然后要查询表 s ,你必须使用JOIN,如在elanoism的答案中所解释的那样。

坏事™

我不能或不想这样做,你可能不得不依赖FIND_IN_SET功能。

SELECT * FROM bad WHERE FIND_IN_SET(target_value, comma_separated_values) > 0;

请参阅http://sqlfiddle.com/#!2/29eba/2

顺便说一下,为什么这是坏事?因为如您所见,对多值列编写查询并不容易 - 但是,更重要的是,您无法在该列上使用索引,因此也无法轻松执行连接操作或强制执行参考完整性。

马马虎虎啊

作为最后一点,如果可能值的集合很小(小于65),则另一种方法是将列类型更改为SET()