我需要從SQL表字段的前10個字選擇查詢。從SQL表中選擇前10個字表
我有字段名稱:說明,所以我需要從描述字段的前10個單詞。
EX:描述:我對這個答案不滿意;我不喜歡GROUP BY,我寧願不做數字表。希望有人能接我。
輸出:我對這個答案感覺不好,我不喜歡
我需要從SQL表字段的前10個字選擇查詢。從SQL表中選擇前10個字表
我有字段名稱:說明,所以我需要從描述字段的前10個單詞。
EX:描述:我對這個答案不滿意;我不喜歡GROUP BY,我寧願不做數字表。希望有人能接我。
輸出:我對這個答案感覺不好,我不喜歡
您可以檢查this答案,以瞭解如何在SQL Server
的上下文中實現和使用.net
函數。在這裏,我正在使用SQLSCLR
執行.net
Regex.Match
函數。
DECLARE @DataSource TABLE
(
[Description] NVARCHAR(MAX)
);
INSERT INTO @DataSource ([Description])
VALUES ('word01, word02, word03, word04, word05, word06')
,('word01,word02, word03, word04, word05, word06')
,('word01!word02, word03: word04, word05, word06');
SELECT *
FROM @DataSource DS
CROSS APPLY [dbo].[fn_Utils_RegexMatches] ([Description], '^(\w+\b.*?){3}') RM;
這給你以下的輸出:
這也太詳細(和extraging只有第一個three
話)。你最終的查詢可以是這樣的:
SELECT DS.[Description], RM.[CaptureValue]
FROM @DataSource DS
CROSS APPLY [dbo].[fn_Utils_RegexMatches] ([Description], '^(?n)(\w+\b.*?){3}') RM;
總之,使用正則表達式,你可以使用你想要的任何分離器,但更重要的是,你可以在T-SQL
上下文中執行.net
代碼這是巨大的。
你有很多要閱讀和從這裏學習。以前的答案更容易和更快實施。
巨大的內存消耗和延遲。即使使用最仔細的編碼,正則表達式也會生成匹配樹,無論您是否需要結果。這些查詢被寫入的方式,它將爲* all *行這樣做。有一個原因SQLCLR字符串拆分方法*不*使用正則表達式 –
是的,你是對的。您需要測試每次您的解決方案,以確保它能按照您的生產數據預期的那樣工作。這僅是SQLCLR的演示。 – gotqn
這是一個示範鏈接。如果您搜索'T-SQL string split',您會發現各種SQLCLR實現。最快速地枚舉字符直接只要需要。速度與SQL Server 2016的STRING_SPLIT相當。如果你只需要100個單詞中的10個單詞,這是一個巨大的進步 –
left()函數是否正常?
從your_table中選擇left(Description,10);
這將返回前10個字符,而不是前10個字 –
另一種選擇是使用CROSS APPLY和一點XML。 CROSS APPLY中的邏輯可以輕鬆移植到UDF(標量或表值)中。
例
Declare @YourTable table (ID int,LongDesc varchar(max))
Insert into @YourTable values
(1,'I don''t feel good about this answer; I don''t like the GROUP BY and I would rather not do the table of numbers. Hopefully somebody can pick me up on this.')
Select A.ID
,ShortDesc = B.S
From @YourTable A
Cross Apply (
Select S = xDim.value('/x[1]','varchar(100)')+' '
+xDim.value('/x[2]','varchar(100)')+' '
+xDim.value('/x[3]','varchar(100)')+' '
+xDim.value('/x[4]','varchar(100)')+' '
+xDim.value('/x[5]','varchar(100)')+' '
+xDim.value('/x[6]','varchar(100)')+' '
+xDim.value('/x[7]','varchar(100)')+' '
+xDim.value('/x[8]','varchar(100)')+' '
+xDim.value('/x[9]','varchar(100)')+' '
+xDim.value('/x[10]','varchar(100)')
From (Select Cast('<x>' + replace((Select replace(A.LongDesc,' ','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml) as xDim) as A
) B
返回
ID ShortDesc
1 I don't feel good about this answer; I don't like
@maSTArHiAn我都是基準測試,並且在我錯誤時願意承認。但是,在這種情況下,我的方法更快。對100K記錄進行一系列基準測試。每個運行5次。我的方法平均爲161毫秒。你的方法377毫秒。 –
我明白了。有什麼機會向我展示你是如何做到這一點的? – maSTAShuFu
我應該說你使用了什麼工具? – maSTAShuFu
與大數據試試這個。
DECLARE @T TABLE(COL1 NVARCHAR(MAX))
INSERT INTO @T VALUES
('I dont feel good about this answer; I dont like the GROUP BY and I would rather not do the table of numbers. Hopefully somebody can pick me up on this.')
;WITH CTE AS
(
select col1,substring(col1,1,CHARINDEX(' ',col1))Words
,substring(col1,CHARINDEX(' ',col1)+1,len(col1))Residue
, 1 rn from @t
union ALL
select col1,substring(Residue,1,CHARINDEX(' ',Residue))
,substring(Residue,CHARINDEX(' ',Residue)+1,len(Residue))
,rn+1
from cte
where len(Words)>0 and rn<10
)
SELECT Words FROM cte
將需要60ms運行 – maSTAShuFu
@maSTArHiAn,我剛剛測試,爲10,000行(這意味着輸出是1,00,000行)平均時間爲6ms.can你扔樣本數據 – KumarHarsh
執行耗時不寫時間。 – maSTAShuFu
我知道你已經有一個答案,但我只是想以不同的方式來做。
DECLARE @WORD VARCHAR(8000)= 'I don''t feel good about this answer; I don''t like the GROUP BY and I would rather not do the table of numbers. Hopefully somebody can pick me up on this.'
DECLARE @LOOP INT = 1
DECLARE @STR_POS INT = 1
DECLARE @CI INT
DECLARE @RES_STR VARCHAR(8000) = ''
WHILE(@LOOP<=10)
BEGIN
SELECT @CI = CHARINDEX(' ',@WORD,@STR_POS)
SELECT @RES_STR = @RES_STR +' '+ SUBSTRING(@WORD,@STR_POS,(CHARINDEX(' ',@WORD,@STR_POS)[email protected]_POS))
SET @STR_POS = @CI+1
SET @[email protected]+1
END
PRINT @RES_STR
這不會給你一個行解決方案,但另一個選項解析出前十個單詞使用類似的技術與較少的代碼,純粹爲了說明..我想這可以轉換爲用戶定義的函數,但我們知道它們表現不佳。它可能可以使用CrossApply進行組合以消除對UDF的需求。我必須以XML語法貸記本求救:https://www.mssqltips.com/sqlservertip/1771/splitting-delimited-strings-using-xml-in-sql-server/
DECLARE
@xml as xml,
@str as varchar(1000)= 'I don''t feel good about this answer; I don''t like the GROUP BY and I would rather not do the table of numbers. Hopefully somebody can pick me up on this.',
@delimiter as char(1) = char(32),
@xmlspace as char(13) = '<y> </y>'
SET @xml = cast(('<x>'+replace(@str,@delimiter,@xmlspace)+'</x>') as xml)
SELECT TOP 10 N.value('.', 'varchar(50)') FROM @xml.nodes('x') as T(N)
這需要43ms才能運行 – maSTAShuFu
可以請你試試這個
declare @message nvarchar(max) = 'I don''t feel good about this answer; I don''t like the GROUP BY and I would rather not do the table of numbers. Hopefully somebody can pick me up on this'
SELECT left(@message,
CHARINDEX(' ', @message,
CHARINDEX(' ', @message,
CHARINDEX(' ',@message,
CHARINDEX(' ',@message,
CHARINDEX(' ',@message,
CHARINDEX(' ',@message,
CHARINDEX(' ',@message,
CHARINDEX(' ',@message,
CHARINDEX(' ',@message,
CHARINDEX(' ',@message) + 1) + 1) + 1) + 1) + 1) + 1) + 1)+ 1) + 1))
問候
請加預期的輸出,輸入和你嘗試過什麼到目前爲止 – TheGameiswar
看這裏瞭解更多關於如何提出完美的問題:https://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/ – TheGameiswar
* What * answers你在說什麼?在任何情況下,數字表格可以讓事情更快*。問題本身就是問題 - 它非常含糊。無論如何,SQL不是一個字符串操作語言。這不是你是否喜歡查詢,而是它是否以最有效的方式產生結果 –