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

问题描述

我正在尝试执行一条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这样的单个变量,则可以正常工作。但是现在我们需要搜索更多......

所以uname现在有一个可能的列表,例如“ abc1,abc2,abc3,abc4”

现在#send_to_var#还可以包含多个变量,例如“ abc3,efd6,asc9”

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

任何人都可以提供任何建议吗?

解决方法

如果您使用的是SQL Server 2016,则有一个STRING_SPLIT函数会将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 != ''

从问题中的示例数据中假设,您的列表定界符为,,不带空格,并且该列表中存储的值中不允许有未转义的,字符。

如果表很大,则前导通配符会使速度变慢。但是,与数据设计相比,这是您最少的担心。最好请有时间负责的人进行大修!