Как использовать сплит в SQL Server 2005? - PullRequest
1 голос
/ 17 марта 2010

Столбец таблицы содержит значения, разделенные запятой, например: (1,2,3)

Как разделить это как

1
2
3

или

1  2   3

в SQL Server 2005.

Ответы [ 2 ]

1 голос
/ 17 марта 2010

Встроенной функции нет, но вот сообщение на форуме, в котором люди показывают множество методов. Там есть несколько конкретных примеров 2005 года. Я использовал пару из них раньше. http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=50648

Вот один, возвращает таблицу.

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
0 голосов
/ 17 марта 2010

Есть много способов разделить строку в SQL Server 2005. В этой статье рассматриваются преимущества и недостатки практически каждого метода:

«Массивы и списки в SQL Server 2005 и более поздних версиях, когда параметры табличных значений не обрезают его» Эрланда Соммарского

Вам необходимо создать функцию разделения. Вот как можно использовать функцию разделения:

SELECT
    *
    FROM YourTable                               y
    INNER JOIN dbo.yourSplitFunction(@Parameter) s ON y.ID=s.Value

Я предпочитаю подход с использованием таблиц чисел для разделения строки в TSQL , но существует множество способов разделения строк в SQL Server, см. Предыдущую ссылку, которая объясняет за и против каждого из них.

Чтобы метод таблицы чисел сработал, необходимо выполнить настройку единой таблицы, которая создаст таблицу Numbers, содержащую строки от 1 до 10000:

SELECT TOP 10000 IDENTITY(int,1,1) AS Number
    INTO Numbers
    FROM sys.objects s1
    CROSS JOIN sys.objects s2
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)

После настройки таблицы Numbers создайте функцию разделения:

CREATE FUNCTION [dbo].[FN_ListToTable]
(
     @SplitOn  char(1)      --REQUIRED, the character to split the @List string on
    ,@List     varchar(8000)--REQUIRED, the list to split apart
)
RETURNS TABLE
AS
RETURN 
(

    ----------------
    --SINGLE QUERY-- --this will not return empty rows
    ----------------
    SELECT
        ListValue
        FROM (SELECT
                  LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue
                  FROM (
                           SELECT @SplitOn + @List + @SplitOn AS List2
                       ) AS dt
                      INNER JOIN Numbers n ON n.Number < LEN(dt.List2)
                  WHERE SUBSTRING(List2, number, 1) = @SplitOn
             ) dt2
        WHERE ListValue IS NOT NULL AND ListValue!=''

);
GO 

Теперь вы можете легко разбить строку CSV на таблицу и присоединиться к ней:

select * from dbo.FN_ListToTable(',','1,2,3,,,4,5,6777,,,')

ВЫВОД:

ListValue
-----------------------
1
2
3
4
5
6777

(6 row(s) affected)

Вы можете использовать строку CSV следующим образом, а не временную таблицу:

SELECT * FROM tblMyTable 
INNER JOIN /*Bunch of inner joins here*/ 
WHERE ItemID IN (select ListValue from dbo.FN_ListToTable(',',@MyList));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...