我怎样才能逆IN语法?
Posted
技术标签:
【中文标题】我怎样才能逆IN语法?【英文标题】:How can i make inverse of IN Syntax? 【发布时间】:2011-06-05 14:39:15 【问题描述】:如果我有类似的代码
$vals = "50,60,40";
输入 SQL
"SELECT * FROM TABLE WHERE col IN( $vals )"
如果我有一个像 50 这样的值并且我在 SQL 中的 col 包含“50,40,60”,则否
如何选择它
我的意思是 IN 语法的逆向
如果我在 sql 中有表包含类似的值
Firstname | Lastname | Age | Hobbies
Ahmed | Ali | 50 | run,swim
Mohammed | Ahmed | 30 | run
如果我想要谁可以在爱好中游泳
【问题讨论】:
如果您的列包含逗号分隔值,这几乎总是表明您的架构不正确。通常,您会为值使用单独的表,而不是将它们存储在用逗号分隔的单个列中。 我看不到他在哪里有一个包含 csv 的列。我认为他假设数据库会将他的 csv 分解为一系列。显然它没有,并尝试查看是否存在值为“50,60,70”的给定列,我怀疑它会。他首先需要一个 split 函数,以便在他的 $vals 变量中独立地看到每个值。FIND_IN_SET(value,column) !=0
可以提供帮助,但您应该接受@tvanfosson 的建议,因为它既是维护的噩梦,又不能利用密钥,所以它会比需要的慢很多。
【参考方案1】:
我的意思是 IN 语法的逆向
你可以使用
NOT IN
运算符如果你有一个好的表结构。
您应该为Hobbies
创建一个表,然后为您的person
表添加一个relanshionship,因为现在完成此操作的唯一方法是使用包含大量LIKE
条件的丑陋SQL。
【讨论】:
不——这不是他想要的。 那么the inverse of IN Syntax
是什么?
@yes123 - 他想要where col like '%50,' or col like '%,50,%' or col like '%,50' ...
之类的东西,因为他只有一个值,并且该列可能包含多个值。更大的问题是表结构可能是错误的,值不应存储在单个列中,而应存储在单独的表中。
@yes:我知道,我也喜欢只看标题就开始回答问题。但是,如果您阅读了实际问题,您就会知道您所写的内容并没有回答它。
@yes: "如果我有一个像 50 这样的值并且我在 SQL 中有 col 包含 "50,40,60" 我该如何选择它"。 PS:我不是想冒犯你或类似的东西。我只是要求你删除这个离题的答案。【参考方案2】:
检查FIND_IN_SET()函数:
"SELECT * FROM TABLE WHERE FIND_IN_SET('swim', Hobbies) > 0"
【讨论】:
这仅对 mysql 有效。这是一个合理的假设,因为问题被标记为 php,但我们将 PHP 与 MSSQL 以及 MySQL 一起使用,它不适用于 MSSQL。 好点。此外,仍然基于这个假设,如果您的爱好列表不太可能发展,将其声明为SET
会更快,因为它将使用位算术而不是字符串比较。
@yes:这甚至适用于非 SET 列:SELECT FIND_IN_SET('swim', 'run,swim')
=> 2
@Yes123:是的,它确实有效,检查文档,这也适用于逗号分隔的纯字符/文本列。【参考方案3】:
我建议您更改架构以将值存储在单独的表中,并使用原始列的 FK。
People
ID - PK
FirstName
LastName
Hobbies
ID -- PK
Person_ID -- FK to People
Hobby -- store your comma-separated values here
那你就可以了
select People.ID, People.FirstName, People.LastName
from People
inner join Hobbies on People.ID = Hobbies.Person_ID
where Hobbies.Hobby = 'Swimming'
一个更好的结构可能有 3 个表,允许您独立于人们维护一组爱好,并简单地保持每个人与其爱好之间的关系。
People
ID
FirstName
LastName
Hobbies
ID
Hobby
PeopleHobbies
ID
Person_ID
Hobby_ID
与往常一样,考虑您的查询需求并在表上创建合适的索引以实现快速查找和连接。
【讨论】:
我不确定是否需要 TableB 中的 PK(我只是制作 PK(ID_A,val3),并带有一个额外的索引(val3)来加快速度),但基本上,是的,这样做。 @Wrikken - 我总是使用人工 PK,在这种情况下,它会非常有帮助,因为关系是一对多的,人工主键可以让我轻松地从关系中删除一行.更好的结构可能会使用 3 个表,即 People、Hobbies 和 PeopleHobbies。 Ack,3 桌选项可以更好地满足有限的爱好。从来不喜欢关系表中的人工 PK,因为它是非数据的,如果可以的话,我会避免使用它们,但实际上,如果你不这样做,你必须将这两个字段都提供给查询。 @Wrikken - 你可能对这篇文章感兴趣:agiledata.org/essays/keys.html 或这个问题:***.com/questions/3747730/… 这当然值得商榷,但我经常在有很多客户的环境中工作,根据我在具有更多易失数据的环境中的经验,基于自然键删除/修改某些内容(有人添加了关系,另一个/相同的删除它,重新添加它,重新删除它等)在 HTTP 等无状态协议中更加一致(我认为这是因为 PHP 在标签中)。但它当然不是一成不变的,取决于具体情况(例如:关系中的所有字段都应该相当小,最好是 int)等等,等等。以上是关于我怎样才能逆IN语法?的主要内容,如果未能解决你的问题,请参考以下文章