2011-04-29 32 views
5

我有一個varchar(max)字段包含名稱值對,在每一行我有名稱UnderScore值。如何解析一個字符串並從中創建多個列?

我需要做一個查詢反對它,這樣它返回的名稱,在兩列值對(所以通過解析文本,移除下劃線和「新行」字符。

從這個

所以

select NameValue from Table 

從哪裏獲得這樣的文字:

Name1_Value1 
Name2_Value2 
Name3_Value3 

我想有這個輸出

Names Values 
===== ====== 
Name1 Value1 
Name2 Value2 
Name3 Value3 
+0

我關閉這個問題,因爲我問了一個新的,更接近我的真正的問題:http://stackoverflow.com/questions/5830065/how-to-query-a單個備忘錄字段獲取許多結果每行一個 – LaBracca 2011-04-29 08:59:16

+0

無需關閉。你可以編輯你的問題 – 2011-04-29 09:07:51

+0

是的你是對的,我真的很着急! – LaBracca 2011-04-29 09:37:04

回答

6
SELECT substring(NameValue, 1, charindex('_', NameValue)-1) AS Names, 
    substring(NameValue, charindex('_', NameValue)+1, LEN(NameValue)) AS Values 
FROM Table 

編輯: 像這樣的東西放一個函數或存儲過程與臨時表組合應該適用於多條線路,根據線路的分隔符,你也應該刪除CHAR(13)開始之前:

DECLARE @helper varchar(512) 
DECLARE @current varchar(512) 
SET @helper = NAMEVALUE 
WHILE CHARINDEX(CHAR(10), @helper) > 0 BEGIN 
    SET @current = SUBSTRING(@helper, 1, CHARINDEX(CHAR(10), NAMEVALUE)-1) 
    SELECT SUBSTRING(@current, 1, CHARINDEX('_', @current)-1) AS Names, 
     SUBSTRING(@current, CHARINDEX('_', @current)+1, LEN(@current)) AS Names 
    SET @helper = SUBSTRING(@helper, CHARINDEX(CHAR(10), @helper)+1, LEN(@helper)) 
END 
SELECT SUBSTRING(@helper, 1, CHARINDEX('_', @helper)-1) AS Names, 
    SUBSTRING(@helper, CHARINDEX('_', @helper)+1, LEN(@helper)) AS Names 
+0

這將適用於一行,但如何處理更多行? – LaBracca 2011-04-29 08:34:32

+0

所以你的數據庫設計是borken?如果你有多個行,你必須在一個函數或存儲過程中執行此操作。看我的編輯。 – 2011-04-29 09:07:34

+0

不,我需要做的是一種模擬新領域的臨時工作,我沒有時間,當然我會盡快將其刪除。 – LaBracca 2011-04-29 09:36:46

1
DECLARE @TExt NVARCHAR(MAX)= '***[ddd]*** 
    dfdf 
    fdfdfdfdfdf 
    ***[fff]*** 
    4545445 
    45454 
    ***[ahaASSDAD]*** 

    DFDFDF 
    ***[SOME TEXT]*** 
    ' 

    DECLARE @Delimiter VARCHAR(1000)= CHAR(13) + CHAR(10) ; 
    WITH numbers 
       AS (SELECT ROW_NUMBER() OVER (ORDER BY o.object_id, o2.object_id) Number 
        FROM  sys.objects o 
          CROSS JOIN sys.objects o2 
       ), 
      c AS (SELECT Number CHARBegin , 
          ROW_NUMBER() OVER (ORDER BY number) RN 
        FROM  numbers 
        WHERE SUBSTRING(@text, Number, LEN(@Delimiter)) = @Delimiter 
       ), 
      res 
       AS (SELECT CHARBegin , 
          CAST(LEFT(@text, charbegin) AS NVARCHAR(MAX)) Res , 
          RN 
        FROM  c 
        WHERE rn = 1 
        UNION ALL 
        SELECT c.CHARBegin , 
          CAST(SUBSTRING(@text, res.CHARBegin, 
              c.CHARBegin - res.CHARBegin) AS NVARCHAR(MAX)) , 
          c.RN 
        FROM  c 
          JOIN res ON c.RN = res.RN + 1 
       ) 
     SELECT * 
     FROM res 
-1

的CTE你將有一個問題遞歸若再100項

消息530,級別16,狀態1,行20語句終止。語句完成前,最大遞歸100已經耗盡。

DECLARE @TExt NVARCHAR(MAX) 
SET @TExt = '100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203' 


DECLARE @Delimiter VARCHAR(1000)= ','; 
WITH numbers 
      AS (SELECT ROW_NUMBER() OVER (ORDER BY o.object_id, o2.object_id) Number 
       FROM  sys.objects o 
         CROSS JOIN sys.objects o2 
      ), 
     c AS (SELECT Number CHARBegin , 
         ROW_NUMBER() OVER (ORDER BY number) RN 
       FROM  numbers 
       WHERE SUBSTRING(@text, Number, LEN(@Delimiter)) = @Delimiter 
      ), 
     res 
      AS (SELECT CHARBegin , 
         CAST(LEFT(@text, charbegin) AS NVARCHAR(MAX)) Res , 
         RN 
       FROM  c 
       WHERE rn = 1 
       UNION ALL 
       SELECT c.CHARBegin , 
         CAST(SUBSTRING(@text, res.CHARBegin, 
             c.CHARBegin - res.CHARBegin) AS NVARCHAR(MAX)) , 
         c.RN 
       FROM  c 
         JOIN res ON c.RN = res.RN + 1 
      ) 
    SELECT * 
    FROM res 
0

他是你可以用一個例子:

-- Creating table: 
create table demo (dID int, dRec varchar(100)); 

-- Inserting records: 
insert into demo (dID, dRec) values (1, 'BCQP1 Sam'); 
insert into demo (dID, dRec) values (2, 'BCQP2 LD'); 

-- Selecting fields to retrive records: 
select * from demo; 

然後我想在一個單行顯示兩行合併,並從左側取出的名字只顯示值正面朝上空間角色。

/* 
    The STUFF() function puts a string in another string, from an initial position. 
    The LEFT() function returns the left part of a character string with the specified number of characters. 
    The CHARINDEX() string function returns the starting position of the specified expression in a character string. 
*/ 
SELECT 
DISTINCT 
    STUFF((SELECT ' ' + LEFT(dt1.dRec, charindex(' ', dt1.dRec) - 1) 
      FROM demo dt1 
      ORDER BY dRec 
      FOR XML PATH('')), 1, 1, '') [Convined values] 
FROM demo dt2 
-- 
GROUP BY dt2.dID, dt2.dRec 
ORDER BY 1 

正如你可以在這裏看到,當你運行函數的輸出將是:

BCQP1 BCQP2 

在腳本的頂部,我解釋了每個功能用於(STUFF(),左( ),CHARINDEX()函數)我也使用DISTINCT消除重複值。

注:DT代表「演示表」,我用同樣的表,並使用兩個別名DT1和DT2,並DREC代表「演示錄製」

如果您想了解更多有關的東西()函數這裏是一個鏈接:

https://www.mssqltips.com/sqlservertip/2914/rolling-up-multiple-rows-into-a-single-row-and-column-for-sql-server-data/

相關問題