从SQL Server中的列表中获得唯一值

问题描述

我有一个数据库列,其中包含以逗号分隔的列表:

VALUES          ID
--------------------
1,11,32          A
11,12,28         B
1                C
32,1          D

当我运行SQL语句时,在我的WHERE子句中,我尝试了INCONTAINSLIKE,但错误和成功的程度不同,但是没有一个我需要的确切回报。

我需要的是where子句,如果我要在列表中查找所有带有'1'(不是数字)的ID。

问题示例:

WHERE值,例如(1)

这将返回A,B,C,D,因为值(11)中包含1。我希望有ID(A,C,D)。

WHERE值,例如(2)

这将返回A,B,D,因为值(32,28,12)中包含2。我希望零记录。

在此先感谢您的帮助!

解决方法

我将通过引用上面@Jarlh给出的即时评论来开始回答:

永远不要将数据存储为逗号分隔的项目。只会给您带来很多麻烦。

话虽如此,如果您真的对这种设计感到困惑,可以使用:

SELECT *
FROM yourTable
WHERE ',' + [VALUES] + ',' LIKE '%,1,%';

这里的诀窍是将每个VALUES转换成类似以下内容的东西:

,11,12,28,

然后,我们可以搜索两侧带有逗号分隔符的目标号码。由于我们将逗号放在两端,因此现在可以确保CSV列表中的每个数字都带有逗号。

,

如果您坚持使用如此糟糕的数据模型,我建议:

select t.*
from t
where exists (select 1
              from string_split(t.values,',') s
              where s.value = 1
             );
,

我确切地回应了贾尔和蒂姆所说的话。关系模型不是在表中存储逗号分隔的字符串的正确位置。

这是一种方法,如果x列上有一个索引,则可能会使用索引

select distinct x
  from t
 cross apply string_split(t.x,')
where value=1 /*out here you may parameterize,and also could make use of an index each if there is one in value*/ 

+---------+
|    x    |
+---------+
|       1 |
| 1,32 |
| 32,1 |
+---------+

工作示例 https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=b9b3084f52b0f42ffd17d90427016999

-SQL Server较旧的版本

with data
 as (
SELECT t.c.value('.','VARCHAR(1000)') as val,y,x
           FROM (
                 SELECT x1 = CAST('<t>' + 
                             REPLACE(x,'</t><t>') + '</t>' AS XML),x
                   FROM t
                ) a
     CROSS APPLY x1.nodes('/t') t(c)
     )
select x,y
  from data

+---------+
|    x    |
+---------+
|       1 |
| 1,1 |
+---------+

工作示例 https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=011a096bbdd759ea5fe3aa74b08bc895

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...