پست ویرایش شده است
ممنون از پیگیریتون. با مطرح شدن بحث REPLACE کردن، راه حل ها بهینه تر و هوشمندتر شدن.
در واقع در روش پیشینم من آمدم کاراکتر به کاراکتر رشته ها را مورد بررسی قرار داده و هرگاه کاراکتر مورد نظر ما بود انتخاب در غیر اینصورت انتخاب نخواهد شد و این کاراکتر ها با کاراکتر های پیشین الحاق میشدند. که این عملیات، جداسازی کاراکتر، مقایسه کاراکتر و الحاق آن با کاراکتر های پیشین به اندازه طول رشته انجام میشد.
من اسم روش قبل را روش "غیر هوشمندانه" نامگذاری میکنم. به این علت که اگر هیچ کاراکتر ناخواسته هم در رشته نباشد کل رشته کاراکتر به کاراکتر مورد بررسی قرار می گیرد.
بنده قسمت اول کوئریم که مربوط به حذف کاراکترهای ناخواسته بود را هوشمند کردم (تکنیک REPLACE همانکاری که شما انجام دادین) البته به روش شخصی خودم. در اینجا دیگه خبری از ستون Countour نیست و دیگه کاراکترهای زائد نمیان یکبار تبدیل به ▄ بشن و دوباره حذف بشن. یعنی همون بار اول ختمشون خونده میشه .
و همچنین قسمت دوم که مربوط به Split کردن رشته می شود را نیز هوشمند کردم. در اینجا ابتدا کد مربوط به برش رشته را توسط تابع STUFF بسیار ساده تر کردم یعنی بجای کد زیر:
SUBSTRING(S, CHARINDEX(' ', S) + 1, LEN(S) - CHARINDEX(' ', S) + 1)
این کد را قرار دادم:
STUFF(S,1,CHARINDEX(' ', S),'')
و سپس بعد از جداسازی کلمه از رشته، کلمات مشابه این کلمه را که در رشته وجود دارند را با تابع REPLACE پیدا و با کاراکتر '' تعویض کردم. با این کار دیگر کلمات تکراری مجددا عمل جداسازی روی آنها اتفاق نخواهد افتاد با این کار سرعت اجرای کوئری به دلیل کاهش دستورات بالا خواهد رفت.
منظور این کد هست:
REPLACE(STUFF(S,1,CHARINDEX(' ', S),''),
' ' + SUBSTRING(S, 1, CHARINDEX(' ', S)), ' ')
البته اگر کلمات یکسان در رشته پشت سرهم قرار گرفته باشند تابع REPLACE تنها یکی از آنها را حذف خواهد کرد ولی در کل باعث کاهش اجرای دستورات خواهد شد.
بنظر میرسه که این راه حل سریعترین باشه از بین راه حل های مطرح شده تا الان.
WITH PreCTE(id, value) AS
(
SELECT id,
CAST(string_value AS VARCHAR(500))
FROM test_string
UNION ALL
SELECT id,
CAST(REPLACE(value, SUBSTRING(value, PATINDEX('%[^ a-z]%', value), 1), '')
AS VARCHAR(500))
FROM PreCTE
WHERE PATINDEX('%[^ a-z]%', value) > 0
),
CTE(ID, S, St) AS
(
SELECT Id,
CAST(REPLACE(REPLACE(REPLACE(D.value, ' ', ' ▄'), '▄ ', ''), '▄', '') + ' ' AS VARCHAR(500)) ,
CAST('' AS VARCHAR(15))
FROM test_string AS ts
CROSS APPLY (SELECT TOP 1 value
FROM PreCTE AS pc
WHERE ts.id = pc.id
ORDER BY LEN(pc.value) ASC) AS D
UNION ALL
SELECT Id,
CAST(
REPLACE(STUFF(S,1,CHARINDEX(' ', S),''),
' ' + SUBSTRING(S, 1, CHARINDEX(' ', S)), ' ')
AS VARCHAR(500)),
CAST(SUBSTRING(S, 1, CHARINDEX(' ', S)) AS VARCHAR(15))
FROM CTE
WHERE CHARINDEX(' ', S) > 0
)
SELECT d.id, c.list
FROM test_string d
CROSS APPLY
(
SELECT LTRIM(''+st)
FROM CTE
WHERE cte.id=d.id
GROUP BY st
ORDER BY st
FOR XML PATH('')
)c(list)
OPTION(MAXRECURSION 0);
یک نمونه از تجزیه رشته به کلمات تشکیل دهنده آن در حالت غیر هوشمند:
rnk st s
----- --------------- --------------------------------------------------------------------------------------------------------------
1 hasan reza hasan javad bahman ali mahdi alihasan bahman bahman reza bahador hasan hasan ali reza reza havad
2 hasan reza hasan javad bahman ali mahdi alihasan bahman bahman reza bahador hasan hasan ali reza reza havad
3 reza hasan javad bahman ali mahdi alihasan bahman bahman reza bahador hasan hasan ali reza reza havad
4 hasan javad bahman ali mahdi alihasan bahman bahman reza bahador hasan hasan ali reza reza havad
5 javad bahman ali mahdi alihasan bahman bahman reza bahador hasan hasan ali reza reza havad
6 bahman ali mahdi alihasan bahman bahman reza bahador hasan hasan ali reza reza havad
7 ali mahdi alihasan bahman bahman reza bahador hasan hasan ali reza reza havad
8 mahdi alihasan bahman bahman reza bahador hasan hasan ali reza reza havad
9 alihasan bahman bahman reza bahador hasan hasan ali reza reza havad
10 bahman bahman reza bahador hasan hasan ali reza reza havad
11 bahman reza bahador hasan hasan ali reza reza havad
12 reza bahador hasan hasan ali reza reza havad
13 bahador hasan hasan ali reza reza havad
14 hasan hasan ali reza reza havad
15 hasan ali reza reza havad
16 ali reza reza havad
17 reza reza havad
18 reza havad
19 havad
در حالت اصلاح شده:
rnk st s
------ --------------- ------------------------------------------------------------------------------------------------------------
1 hasan reza hasan javad bahman ali mahdi alihasan bahman bahman reza bahador hasan hasan ali reza reza havad
2 hasan reza javad bahman ali mahdi alihasan bahman bahman reza bahador hasan ali reza reza havad
3 reza javad bahman ali mahdi alihasan bahman bahman bahador hasan ali reza havad
4 javad bahman ali mahdi alihasan bahman bahman bahador hasan ali reza havad
5 bahman ali mahdi alihasan bahman bahador hasan ali reza havad
6 ali mahdi alihasan bahman bahador hasan reza havad
7 mahdi alihasan bahman bahador hasan reza havad
8 alihasan bahman bahador hasan reza havad
9 bahman bahador hasan reza havad
10 bahador hasan reza havad
11 hasan reza havad
12 reza havad
13 havad