היכן הפסיק ה-n-י? (מציאת מופע של תת מחרוזת): גרסת ה-String_Split

07/04/2016

לפני למעלה מ-6 שנים, בראשית דרכי כבלוגר, פרסמתי את הפוסט היכן הפסיק ה-n-י? (מציאת מופע של תת מחרוזת):
נתונה טבלה ובה עמודת Subjects עם מקצועות שונים שכל סטודנט לומד –

Create Table T_Students (Name VarChar(50), Subjects VarChar(Max));

Go

Insert Into T_Students

Values    ('Ana','Geography,Literature'),

        ('Beni','Chemistry,Economics,History,Sociology'),

        ('Carmel',''),

        ('Dana','Literature,Economics,Philosophy,Sociology'),

        ('Eli','Zoology,Economics,Geography,History,Science'),

        ('Felicia','Medicine');

Go

image

ויש לשלוף את המקצוע הרביעי (אם יש..) של כל סטודנט.
הפתרון שאז מצאתי, בלוגר צעיר ונרגש שחרד שמא אינו מחדש דבר או סתם מקשקש, היה להשתמש ב-CTE רקורסיבי –

With MyCTE As

(Select Num, 

        Name,

        Subjects,

        [Begin],

        Comma,

        SUBSTRING(Subjects,[Begin],Comma-1) Subject

From    (Select 1 Num,

                Name,

                Subjects+',' Subjects,

                1 [Begin],

                CHARINDEX(',',Subjects+',') Comma

        From    T_Students

        Where   Subjects<>'') T

Union All

Select    Num,

        Name,

        Subjects,

        [Begin],

        Comma,

        SUBSTRING(Subjects,[Begin],Comma-[Begin]) Subject

From    (Select Num+1 Num,

                Name,

                Subjects,

                Cast(Comma As Int)+1 [Begin],

                CHARINDEX(',',Subjects,Comma+1) Comma

        From    MyCTE

        Where   CHARINDEX(',',Subjects,Comma+1)<>0) T)

Select    * 

From    MyCTE

Where    Num=4

Order By Name,

        Num;

image

העולם קצת התקדם הרבה מאז, וגם אני קצת – בבחינת צעד קטן לאדם וגו’, וקול ה-String_Split נשמע בארצנו.
כעת ניתן לעשות זאת כך:

Select * 

From T_Students T

Cross Apply (Select *

            From String_Split(Cast(Subjects As NVarchar(50)),',')

            Order By GetDate()

            Offset 3 Rows Fetch Next 1 Rows Only) OA1;

image

לא יצא לי כל כך להשתמש באופציית ה-Paging מאז שהיא הוצגה בגרסת 2012, אז הנה התגלגלה הזדמנות לידי, ולא החמצתי אותה.
מכיוון שאני מחוייב לכלול בה פסוקית משנה של מיון, אני “ממיין” לפי התאריך (=לא ממיין), וסומך על המערכת שהסט ממויין לפי סדר ההופעה במחרוזת: מדלג על 3 ומציג את ה-1 שלאחר מכן.

כמובן, אם זה לא ברור, בצורה הרבה יותר יעילה מאשר קודם.

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *