Sql 在逗号分隔的文本列中查找唯一值

Sql 在逗号分隔的文本列中查找唯一值,sql,sql-server,sql-server-2008,sql-server-2005,Sql,Sql Server,Sql Server 2008,Sql Server 2005,我有一个用逗号分隔的列“a”,我想在列a中找到所有唯一的值 下面是一个非常简短的示例: Column A 111, 222 333 444 777,999 我需要一个查询,该查询为我提供以下值: Column C 111 222 333 444 777 999 忽略所有评论中提到的表设计的明显问题,接受在一个巨大的表上这样做可能会非常慢的事实,我可以这样做 首先。。。我将创建一个语句,将所有行转换为一个巨大的逗号分隔列表 DECLARE @tmp VarChar(max) SET @tmp

我有一个用逗号分隔的列“a”,我想在列a中找到所有唯一的值

下面是一个非常简短的示例:

Column A
111, 222
333
444
777,999
我需要一个查询,该查询为我提供以下值:

Column C
111
222
333
444
777
999

忽略所有评论中提到的表设计的明显问题,接受在一个巨大的表上这样做可能会非常慢的事实,我可以这样做

首先。。。我将创建一个语句,将所有行转换为一个巨大的逗号分隔列表

DECLARE @tmp VarChar(max)
SET @tmp = ''
SELECT @tmp = @tmp + ColumnA + ',' FROM TableA
然后使用本文描述的表值udf拆分,将大量字符串转换回具有distinct子句的表中,以确保其唯一性

您可以使用in-combation with
outer apply
将行拆分为多行:

select  ltrim(rtrim(s.s)) as colC
from    @t t
cross apply
        dbo.split(',', t.colA) s
完整代码示例:

if object_id('dbo.Split') is not null
    drop function dbo.Split
go
CREATE FUNCTION dbo.Split (@sep char(1), @s varchar(512))
RETURNS table
AS
RETURN (
    WITH Pieces(pn, start, stop) AS (
      SELECT 1, 1, CHARINDEX(@sep, @s)
      UNION ALL
      SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)
      FROM Pieces
      WHERE stop > 0
    )
    SELECT pn,
      SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s
    FROM Pieces
  )
go
declare @t table (colA varchar(max))
insert @t select '111, 223'
union all select '333'
union all select '444'
union all select '777,999';

select  ltrim(rtrim(s.s)) as colC
from    @t t
cross apply
        dbo.split(',', t.colA) s

你应该修复这个设计-它不是关系型的,这也是你产生这样一个问题的原因。这个问题还不够清楚。你的意思是“我想要一个查询,它用逗号分割a列中的值,修剪结果字符串,并为每个值输出一行”?IMHO。重做数据模型。在字段中存储逗号分隔的列表是一种可怕的模式。它违背了关系数据库的目的
if object_id('dbo.Split') is not null
    drop function dbo.Split
go
CREATE FUNCTION dbo.Split (@sep char(1), @s varchar(512))
RETURNS table
AS
RETURN (
    WITH Pieces(pn, start, stop) AS (
      SELECT 1, 1, CHARINDEX(@sep, @s)
      UNION ALL
      SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)
      FROM Pieces
      WHERE stop > 0
    )
    SELECT pn,
      SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s
    FROM Pieces
  )
go
declare @t table (colA varchar(max))
insert @t select '111, 223'
union all select '333'
union all select '444'
union all select '777,999';

select  ltrim(rtrim(s.s)) as colC
from    @t t
cross apply
        dbo.split(',', t.colA) s