none
צריך למצוא מיקום של character ספציפי רק דרך משפט select RRS feed

  • שאלה

  • שלום לכולם,
    יש לי שאלה בקשר למיקום character בתוך string.

    אני מקבל טבלה כזאת

    create table test (id int, cod Varchar (20) )
    
    insert into test values(1 ,'00101100101'),(2,'1000001010010')


     

    ואני צריך למצוא איפה נמצא 1 בכל שדה רק דרך משפט select
    התוצאה הרצויה צריכה להיות:

    מקווה שהסברתי את עצמי מספיק טוב.

    תודה מראש על כל עזרה שתבוא


    • נערך על-ידי Netanelf יום ראשון 22 מרץ 2015 08:51
    יום ראשון 22 מרץ 2015 08:40

תשובות

  • שלום נתנאל, 

    אני אתחיל מהנקודה האחרונה שהעלת:
    "מקווה שהסברתי את עצמי מספיק טוב."

    אי אפשר היה לשאול את השאלה בצורה יותר ברורה ונאותה :-)
    הלוואי שכל משתמש ששואל שאלה יזכור לצרף DDL+DML+תוצאות מצופות.

    כל מה שנאר לנו זה לספק פתרון פשוט ומדובר בפתרון פשוט מאוד, אבל אני אתחיל בהקדמה קטנה מפני שאני רואה שאנשים פונים לכיוונים לא רלוונטיים :-)

    * הדרך הנכונה לגשת לבעיה זו של ניתוח טקסט (Parse) היא באמצעות פונקציות CLR פשוטות.
    באופן תיארוטי ניתן לבצע את הפעולה גם עם פוקנציות T-SQL אבל זה רעיון גרוע מאוד!

    אז לפני שמתחילים אתה חייב להכנס לקישור הבא ולבדוק למה CLR ולא T-SQL. תוריד את המצגת ותעבור תחילה לשקופית מספר 17. תסתכל טב בגרף ותמשיך
    https://gallery.technet.microsoft.com/SQLSaturday-360-SQLCLR-eb99ab7a

    למעשה אם היית מגיע להרצאה שלי בנושא CLR היית רואה את הפתרון מייד :-)

    יש 2 פתרונות פשוטים שניתן לראות במצגת. האחד בעזרת פונקציית SPLIT שהיא פונקציית חובה בכל שרת! והפתרון השני בעזרת ביטויים רגורליים (פתרון יותר טוב במעט במקרה הנוכחי).

    -- Using Regular Expression, RegexMatches function
    select [Index] from Ariely_RegexMatches_fn('00101100101','.')
    where [Text] = '1'
    GO -- OK
    
    -- Using split function
    select SUM(LEN(Item)+1) over (order by id)
    from Ariely_CLRSplitWithID_Fn('00101100101','1')
    GO -- OK

    התוצאה זהה בשני השאילתות מעל (הראשונה מעט יותר יעילה, אבל כניראה שלא תראה הבדלים בטבלאות קטנות).

    הנה דוגמה של הרצת השאילתה על ערך בודד (בעוד רגע אני אדגים לך על טבלה שלמה כמו אצלך):

    הנה הקוד של השאילתה שנותנת את הפתרון בפשטות ובמהירות ובעיקר ביעילות, על הטבלה המלאה שלך:
    שים לב כמה השאילתה פשוטה :-) אבל הרבה יותר חשוב זה שהיא מאוד יעילה.

    select id, [Index] 
    from test
    cross apply Ariely_RegexMatches_fn(cod,'.')
    where [Text] = '1'
    והנה התוצאה המצופה:

    ** הפנקציות RegexMatches וכן הפונקציה Split הן פונקציות מובנות בדוט נט. אני אישית, עובד עם פוקנציות שונות והרבה יותר יעילות, אבל הקוד שלהן מעט יותר מורכב (הקוד בשימוש בפונקציה המובנית הוא שורה אחת... פשוט משתמשים בה, אצלי אני מייצר את הפונקציה מאפס החל מהגדרת ה ienumerator).
    *** הקוד שאני עובד איתו, מבוסס על קוד שמצאתי באינטרנט ושיפרתי מעט. נסה לחפש את צירוף המילים RegexMatches וכמובן SQLCLR.


    signature   Ronen Ariely
     [Personal Site]    [Blog]    [Facebook]




    • נערך על-ידי pituachMVP, Editor יום ראשון 22 מרץ 2015 15:16
    • סומן כתשובה על-ידי Netanelf יום ראשון 22 מרץ 2015 15:52
    יום ראשון 22 מרץ 2015 14:19
    מנחה דיון

כל התגובות

  • התכוונת לזה?


    SELECT id, CHARINDEX('1', cod)
    from test


    Best Regards,

    Itai Binyamin, MVP

    www.ItaiBinyamin.Blogspot.com


    • נערך על-ידי Itai Binyamin יום ראשון 22 מרץ 2015 13:13 .
    • הוצע כתשובה על-ידי Itai Binyamin יום שני 23 מרץ 2015 08:19
    • הצעה כתשובה בוטלה על-ידי pituachMVP, Editor יום שני 23 מרץ 2015 17:01
    יום ראשון 22 מרץ 2015 13:12
  • אם אני מריץ את הפקודה הזו יוצא לי רק המיקום הראשון של 1

    אני רוצה למצוא את המיקום של הספרה אחד בכל שורה כלומר לפי הדוגמה הספרה 1 מופיעה בID 1 במיקום 3,5,6,9,10,12
    והספרה 1 מופיעה בID 2 במיקום 1,7,9,12 

    יום ראשון 22 מרץ 2015 13:33
  • שלום נתנאל, 

    אני אתחיל מהנקודה האחרונה שהעלת:
    "מקווה שהסברתי את עצמי מספיק טוב."

    אי אפשר היה לשאול את השאלה בצורה יותר ברורה ונאותה :-)
    הלוואי שכל משתמש ששואל שאלה יזכור לצרף DDL+DML+תוצאות מצופות.

    כל מה שנאר לנו זה לספק פתרון פשוט ומדובר בפתרון פשוט מאוד, אבל אני אתחיל בהקדמה קטנה מפני שאני רואה שאנשים פונים לכיוונים לא רלוונטיים :-)

    * הדרך הנכונה לגשת לבעיה זו של ניתוח טקסט (Parse) היא באמצעות פונקציות CLR פשוטות.
    באופן תיארוטי ניתן לבצע את הפעולה גם עם פוקנציות T-SQL אבל זה רעיון גרוע מאוד!

    אז לפני שמתחילים אתה חייב להכנס לקישור הבא ולבדוק למה CLR ולא T-SQL. תוריד את המצגת ותעבור תחילה לשקופית מספר 17. תסתכל טב בגרף ותמשיך
    https://gallery.technet.microsoft.com/SQLSaturday-360-SQLCLR-eb99ab7a

    למעשה אם היית מגיע להרצאה שלי בנושא CLR היית רואה את הפתרון מייד :-)

    יש 2 פתרונות פשוטים שניתן לראות במצגת. האחד בעזרת פונקציית SPLIT שהיא פונקציית חובה בכל שרת! והפתרון השני בעזרת ביטויים רגורליים (פתרון יותר טוב במעט במקרה הנוכחי).

    -- Using Regular Expression, RegexMatches function
    select [Index] from Ariely_RegexMatches_fn('00101100101','.')
    where [Text] = '1'
    GO -- OK
    
    -- Using split function
    select SUM(LEN(Item)+1) over (order by id)
    from Ariely_CLRSplitWithID_Fn('00101100101','1')
    GO -- OK

    התוצאה זהה בשני השאילתות מעל (הראשונה מעט יותר יעילה, אבל כניראה שלא תראה הבדלים בטבלאות קטנות).

    הנה דוגמה של הרצת השאילתה על ערך בודד (בעוד רגע אני אדגים לך על טבלה שלמה כמו אצלך):

    הנה הקוד של השאילתה שנותנת את הפתרון בפשטות ובמהירות ובעיקר ביעילות, על הטבלה המלאה שלך:
    שים לב כמה השאילתה פשוטה :-) אבל הרבה יותר חשוב זה שהיא מאוד יעילה.

    select id, [Index] 
    from test
    cross apply Ariely_RegexMatches_fn(cod,'.')
    where [Text] = '1'
    והנה התוצאה המצופה:

    ** הפנקציות RegexMatches וכן הפונקציה Split הן פונקציות מובנות בדוט נט. אני אישית, עובד עם פוקנציות שונות והרבה יותר יעילות, אבל הקוד שלהן מעט יותר מורכב (הקוד בשימוש בפונקציה המובנית הוא שורה אחת... פשוט משתמשים בה, אצלי אני מייצר את הפונקציה מאפס החל מהגדרת ה ienumerator).
    *** הקוד שאני עובד איתו, מבוסס על קוד שמצאתי באינטרנט ושיפרתי מעט. נסה לחפש את צירוף המילים RegexMatches וכמובן SQLCLR.


    signature   Ronen Ariely
     [Personal Site]    [Blog]    [Facebook]




    • נערך על-ידי pituachMVP, Editor יום ראשון 22 מרץ 2015 15:16
    • סומן כתשובה על-ידי Netanelf יום ראשון 22 מרץ 2015 15:52
    יום ראשון 22 מרץ 2015 14:19
    מנחה דיון