Разделение столбца в SQL, а затем поиск каждого в другой таблице - PullRequest
1 голос
/ 04 марта 2011

Я не уверен, возможно ли это в SQL, и если нет, я сделаю это программно - но было бы замечательно, если бы был способ.

В принципе, у меня есть столбец втаблица, которая заполняется идентификаторами из другой таблицы, разделенными запятыми - поэтому поле может выглядеть следующим образом:

3,4,9

Они ссылаются на другую таблицу, где числа вполе выше является первичным ключом строки.В строке есть описание, которое я хочу отобразить пользователю, а не цифры.

Таким образом, в основном, вместо того, чтобы показывать пользователю 3,4,9, я хочу посмотреть их соответствующие описания в другомТаблица.Возможно ли это?

Ответы [ 4 ]

2 голосов
/ 04 марта 2011

Вы можете написать табличную функцию, которая выполняет разбиение, а затем объединить этот результат с вашей таблицей поиска.

1 голос
/ 07 марта 2011

Крис,

Есть способ сделать это в T-SQL, и на самом деле это довольно просто. Во-первых, вам нужно создать функцию, подобную следующей ... (новый метод, использующий "Tally" cte, основанный на нуле, это противно быстро, потому что он не объединяет разделители).

 CREATE FUNCTION dbo.DelimitedSplit8KNEW
--===== Created by Jeff Moden (Prototype: Testing Still in Progress)
--===== Define I/O parameters
        (
        @pString    VARCHAR(8000),
        @pDelimiter CHAR(1)
        )
RETURNS TABLE
   WITH SCHEMABINDING
     AS
 RETURN
WITH 
      E1(N) AS (
                SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
                SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
                SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
               ),                          --10
      E2(N) AS (SELECT 1 FROM E1 a, E1 b), --100
      E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10,000
cteTally(N) AS (
                SELECT 0 UNION ALL
                SELECT ROW_NUMBER() OVER (ORDER BY N) FROM E4
               )
 SELECT ItemNumber = ROW_NUMBER() OVER(ORDER BY t.N),
        ItemValue  = SUBSTRING(@pString,t.N+1,ISNULL(NULLIF(CHARINDEX(@pDelimiter,@pString,t.N+1),0),DATALENGTH(@pString)+1)-t.N-1)
   FROM cteTally t
  WHERE t.N BETWEEN 0 AND DATALENGTH(@pString)
    AND (SUBSTRING(@pString,t.N,1) = @pDelimiter OR t.N = 0)
;
GO

Теперь, чтобы увидеть, как это используется ... допустим, у вас есть таблица с уникальным столбцом и столбец CSV следующим образом (это также строит данные). Все, что нам нужно сделать, это ПРИМЕНИТЬ КРЕСТОВУЮ исходные данные с помощью функции, и данные будут волшебным образом разделены и готовы к объединению с другой таблицей:

--===== This just builds some test data 
     -- and is not a part of the solution
 SELECT *
   INTO #TestTable
   FROM (
         SELECT 1,'3,4,9'   UNION ALL
         SELECT 2,'3,2,100' UNION ALL
         SELECT 3,'14,35,8,21,27,12'
        ) d (RowNum,CsvValue)
;
--===== Split the data out giving the unique RowNum
     -- from the original data, the element position,
     -- the the value of the split element.  You can
     -- join this SELECT with a table to get the other
     -- values.
 SELECT data.RowNum, split.ItemNumber, split.ItemValue
   FROM #TestTable data
  CROSS APPLY dbo.DelimitedSplit8KNEW(data.CsvValue,',') split
;

Вот вывод ...

RowNum      ItemNumber           ItemValue
----------- -------------------- ---------
1           1                    3
1           2                    4
1           3                    9
2           1                    3
2           2                    2
2           3                    100
3           1                    14
3           2                    35
3           3                    8
3           4                    21
3           5                    27
3           6                    12

(12 row(s) affected)
0 голосов
/ 04 марта 2011

Заинтересованы ли вы в изменении вашей схемы? Вообще, хранить несколько фрагментов данных в одном поле - ужасная практика. Отношение один ко многим кажется более подходящим.

0 голосов
/ 04 марта 2011

Возможно, вы захотите взглянуть на это:

http://www.sommarskog.se/arrays-in-sql.html

И использовать это для выполнения подзапроса с предложением IN.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...