FIND_IN_SET() vs IN(), StackOverFlow上的一个问题

通过一个实例简述数据库查询里FIND_IN_SET() 和IN()区别


问题: 

数据库中有两个表: Orders 和 Companies

Orders的表结构:

OrderID     |     attachedCompanyIDs
------------------------------------
   1                     1,2,3
   2                     2,4

Campany表结构:

CompanyID      |        name
--------------------------------------
    1                 Company 1
    2                 Another Company
    3                 StackOverflow
    4                 Nothing

想要查询的数据为: ID为1的order对应的全部Company的名字.

楼主给出两种查询方式:

第一种:

SELECT name FROM orders,company
WHERE orderID = 1 AND FIND_IN_SET(companyID, attachedCompanyIDs)
工作正常. 查询结果如下:

name
---------------
Company 1
Another Company
StackOverflow

第二种:

SELECT name FROM orders,company
WHERE orderID = 1 AND companyID IN (attachedCompanyIDs)
出现问题, 查询结果如下:

name
---------------
Company 1
Another Company
StackOverflow

作何解释?


答案:

使用关键字IN时, 会自动对值的类型进行转换, 然后在进行操作. 在上面的情况中

SELECT  name
FROM    orders,company
WHERE   orderID = 1
        AND companyID IN (attachedCompanyIDs)

attachedCompanyIDs 的值将被转化成INT (也就是CompanyID的类型), 所以这里字符串"1,2,3"在转换过程中会变成1(到第一个非数字位停止转换). 因此,

companyID IN ('1,2,3') ≡ companyID IN (CAST('1,2,3' AS INT)) ≡ companyID IN (1)


在PostgreSQL中, 你可以使用如下方法把字符串转化成数组:

SELECT  name
FROM    orders
JOIN    company
ON      companyID = ANY (('{' | attachedCompanyIDs | '}')::INT[])
WHERE   orderID = 1
但是MySQL暂不支持. 你可以在这个链接里面找到一些有趣的文章:


原文地址: http://stackoverflow.com/questions/4155873/find-in-set-vs-in


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值