我有一个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列表中?
答案 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()
。