2015-11-11 87 views
3

我在sql數據(只是要注意:SQL STudioIDE),如:獲取第一2特殊字符之間的字符在SQL

data 
a_10_b_c 
a_1_b_c 

我想前兩個符號_之間獲取數據:

Output 
10 
1 
+1

你現在的查詢是什麼? –

+0

FROM [SecCharDB]。[FROM Location] FROM [SecCharDB]。[END_CODE] dbo]。[locationmapping] - 類似這樣的東西,但這不起作用 –

+1

哪個RDBMS是這樣的?請添加一個標籤來指定您是使用'mysql','postgresql','sql-server','oracle'還是'db2' - 或者其他的東西。 –

回答

4

這將是我的做法:

SELECT CAST('<x>' + REPLACE(data,'_','</x><x>') + '</x>' AS XML).value('/x[2]','int') 
FROM YourTable 

首先你改變這個到XML,然後你選擇的第二個節點..

編輯:其他一些例子,這種方法是有用的:

交叉應用:你可以使用這種方法來獲得onc的幾個令牌Ë

DECLARE @tbl TABLE(separated VARCHAR(100)); 
INSERT INTO @tbl VALUES('1_23:50_Look_this_is_a_test'),('2_12:00_that''s_one_more_test'),('3_13:30_great!_It_works!'); 

SELECT Converted.value('/x[1]','int') AS number 
     ,Converted.value('/x[2]','time') AS time 
     ,Converted.value('/x[3]','varchar(max)') AS text 
FROM @tbl 
CROSS APPLY(SELECT CAST('<x>' + REPLACE(separated,'_','</x><x>') + '</x>' AS XML) AS Converted) AS MySeparated 
--type-safe and easy: 
/* 
number time text 
1  23:50 Look 
2  12:00 that's 
3  13:30 great! 
*/ 
GO 

CTE:用作參數

DECLARE @Parameter VARCHAR(100)='1_12:30_SomeValue'; 
WITH MyParameters AS 
(
    SELECT CAST('<x>' + REPLACE(@Parameter,'_','</x><x>') + '</x>' AS XML).value('/x[1]','int') AS IntParam 
      ,CAST('<x>' + REPLACE(@Parameter,'_','</x><x>') + '</x>' AS XML).value('/x[2]','time') AS TimeParam 
      ,CAST('<x>' + REPLACE(@Parameter,'_','</x><x>') + '</x>' AS XML).value('/x[3]','varchar(max)') AS TextParam 
) 
SELECT IntParam,TimeParam,TextParam 
FROM MyParameters 
/* 
IntParam TimeParam TextParam 
1   12:30:00 SomeValue 
*/ 
GO 

分割字符串:變換列出

DECLARE @MyIDs VARCHAR(100)='3,5,7'; 
SELECT A.B.value('.','int') TheIntValue 
FROM(SELECT CAST('<x>' + REPLACE(@MyIDs,',','</x><x>') + '</x>' AS XML) AS MyListAsXML) AS x 
CROSS APPLY MyListAsXML.nodes('/x') AS A(B) 

/* 
TheIntValue 
3 
5 
7 
*/ 
GO 

動態報表

DECLARE @tbl TABLE(ID INT,Content VARCHAR(max)); 
INSERT INTO @tbl VALUES(1,'Value 1'),(2,'Value 2'),(3,'Value 3'),(4,'Value 4'),(5,'Value 5'),(6,'Value 6'),(7,'Value 7'); 

DECLARE @MyIDs VARCHAR(100)='3,5,7'; 
/* 
This won't work (due to the fact, that @MyIDs is not a list of INTs but a text 
SELECT * FROM @tbl WHERE ID IN(@MyIDs) 
*/ 
WITH AsList AS 
(
    SELECT A.B.value('.','int') TheIntValue 
    FROM(SELECT CAST('<x>' + REPLACE(@MyIDs,',','</x><x>') + '</x>' AS XML) AS MyListAsXML) AS x 
    CROSS APPLY MyListAsXML.nodes('/x') AS A(B) 

) 
SELECT * FROM @tbl WHERE ID IN(SELECT TheIntValue FROM AsList) 

/* 
ID Content 
3 Value 3 
5 Value 5 
7 Value 7 
*/ 
+0

這是超級酷,謝謝 –

+0

@VasistaKrishnaBaderdinni,我更喜歡這種方法,因爲兩個原因:第一:你可以立即選擇所有需要的節點。第二:你得到的值類型安全... – Shnugo

+0

它也解決了我的目的,因爲我想加入,然後找到或拆分,我希望它隨時隨地收集信息到Python進行數據分析 –

2

你可以用嵌套的字符串函數做到這一點。通常情況下,這是更簡單的使用outer apply

select t3.output 
from t outer apply 
    (select stuff(t.col, 1, charindex('_', t.col), '') as col2 
    ) t2 outer apply 
    (select left(t2.col2, charindex('_', t2.col2)) as output 
    ) t3; 
相關問題