SQL Select语句,其中位于两个列表之间

SQL Select语句,其中位于两个列表之间,sql,sql-server,string,sql-server-2012,coldfusion,Sql,Sql Server,String,Sql Server 2012,Coldfusion,我正在尝试执行select语句: SELECT group_id FROM ACCOUNT_GROUPS WHERE account_id = '1' AND admin_user = '0' AND active = '1' AND uname IN (<cfqueryparam value="#send_to_var#" cfsqltype="cf_sql_varchar" list="yes" />

我正在尝试执行select语句:

SELECT group_id
FROM ACCOUNT_GROUPS 
WHERE account_id = '1' 
  AND admin_user = '0' 
  AND active = '1' 
  AND uname IN (<cfqueryparam value="#send_to_var#" cfsqltype="cf_sql_varchar" list="yes" />) 
  AND uname != ''
如果uname是像abc1一样的单个var,那么它可以正常工作。但现在我们需要搜索更多

所以联塞特派团现在有一个类似abc1、abc2、abc3、abc4的潜在名单

现在,send_to_var还可以包含多个var,如abc3、efd6、asc9

所以我尝试了CONTAINS和其他SQL技术,但一直遇到问题


有人能提供任何建议吗?

如果您使用的是SQL Server 2016,则有一个字符串分割函数,可以将uname列拆分为一个表,您可以使用列表cfqueryparm进行搜索。您的查询将类似于:

SELECT group_id
FROM ACCOUNT_GROUPS 
WHERE account_id = '1' 
  AND admin_user = '0' 
  AND active = '1' 
  AND EXISTS ( SELECT * FROM STRING_SPLIT (uname,',') 
    WHERE VALUE IN (<cfqueryparam value="#send_to_var#" cfsqltype="cf_sql_varchar" list="yes" />) 
  AND uname != ''

性能可能会很糟糕——这被认为是糟糕的数据设计。如果您的SQL Server不支持STRING_SPLIT,那么还有其他解决方案,从坏到坏。编辑您的问题以发布您的SQL Server版本。

正如其他人已经解释的那样,这看起来像讨厌的DB设计。但是,如果你真的被迫坚持使用它,并且你没有STRING_SPLIT支持,那么一个可怕的黑客将是:

SELECT group_id
FROM ACCOUNT_GROUPS 
WHERE account_id = '1' 
  AND admin_user = '0' 
  AND active = '1' 
  AND (1=0 <cfloop list="#send_to_var#" index="thisItem"> OR ','+uname+',' LIKE <cfqueryparam cfsqltype="cf_sql_varchar" value="%,#thisItem#,%" /> </cfloop>)
  AND uname != ''
根据问题中的示例数据,假设列表分隔符不带空格,并且存储在该列表中的值中不允许有未转义的字符


如果表很大,则前导通配符将使其变慢。但与数据设计相比,这是您最不担心的。最好向负责人求情,争取时间彻底解决这个问题

听起来像是一个规范化问题。但当我研究这个问题时,我们有了MS-SQL 2012。字符串拆分是在2012年提供,还是仅在2016年及以后才提供?谢谢你确定你的代码不起作用?在我看来,问题中的编码方式非常好。我唯一一次在CF中使用IN子句时遇到问题,因为它使用单个值,但使用值列表时失败,那是因为我忘记了使用list=yes选项,而您显然使用了该选项。@user12031119-这是因为他们在uname列中存储了多个值的列表:-类似这样的问题是原因之一不推荐!Scott,更好的方法是规范化。将uname值存储在单独的行中,而不是存储在单个列中!在规范化方法中,他们可以创建一个新的表ACCOUNT\u GROUPS\u XREF来存储规范化数据,然后创建一个名为ACCOUNT\u GROUPS的视图,该视图以当前表的格式返回规范化数据。然后删除/重命名现有表,当前查询将继续对视图进行操作,而无需重构。我打赌不做任何事情将字符串\u拆分列表放入派生表子查询中,并执行连接,以使其能够命中索引或优化为排序合并连接。我尽量避免在,良好的数学设置,但糟糕的查询!EXISTS适用于索引相关子查询,而不是这个。@DavidG.Pickett请确保我理解。它们可能是uname上的一个索引,但因为我们使用的是STRING_SPLIT,所以该索引没有帮助。没关系。我看到他们正在存储列表:-啊!同意这是一个糟糕的db设计,应该规范化@实际上,SQL Server将在查询计划中以最佳方式进行转换。它可能看起来像一个字面上的比较,在第一次匹配时就会被删掉。您仍然需要为查询表中的次优数据设计付费。@Scott。。。这是一个lof ifs。这些事情中的任何一个出错,查询都无法找到匹配项。正如每个人都说的,存储列表非常脆弱和缓慢的原因有很多,应尽可能避免在该项周围使用逗号,以消除列表中的第一项和最后一项的争用。我的评论与@SevRoberts.Dan的答案有关-该技巧通过在uname值后面附加逗号来起作用。所以它总是找到值,不管它是列表中的第一个、中间的、最后的还是唯一的元素@SOS感谢您理解“领先+落后”技巧;-是的,这是很多假设/假设-但我认为如果其中任何一个都不是真的,那么除了重新设计数据库模式之外,其他任何东西都不会起作用,包括STRING_SPLIT!