SKIP(90).Take(10) איך עושים את זה בSQL SERVER

Gooloosh

New member
SKIP(90).Take(10) איך עושים את זה בSQL SERVER

אני עובדת עם SQL SERVER 2005, יש לי דף עם פייגר, בו אני מציגה נתונים לפי מס' הדף. הבעיה היא שאני לא יודעת איך אני שולפת את 10 הרשומות בהם אני מעונינת, ובעצם בכל דף אני שולפת את כל הרשומות המתאימות (שיכול להיות גם אלפים) מדלגת X*10 רשומות ומציגה 10 בלבד.. איך אני יכולה לעשות שליפה של 10 רשומות בלבד, אבל שידלג על X רשומות לפני כן. (אני לא יכולה להיעזר בID של הטבלה כי לא כל הרשומות בטבלה מתאימות להצגה, ממילא אין לי ID רץ..) בLINQ הייתי משתמשת בSkip(X).Take(01) לא שאני ממש יודעת אם הוא יעיל, אבל זה מה שהייתי עושה.. יש לכם רעיון? לעשות את זה בפרוצדורה זה גם בא בחשבון... רק אשמח לדעת איך, מאוד חשוב לי מהירות השליפה, כי זה משפיע על זמן הטעינה של הדף.. בתודה!
 

pitoach

New member
בכל בלוג שקשור ל SQL אפשר למצוא לפחות

דוגמה אחת הקשורה לנושא זה של פונקציות LAG/LEAD. פונקציות אלו דרך אגב נוספו בגרסת השרת SQL הבאה 2012 ובינתיים פשוט מבצעים זאת בצורה מפורשת. את יכולה לבדוק לבדוק לדוגמה את הקישור הבא ולקחת את הרעיון למקרה שלך: http://ariely.info/dnn/Blog/tabid/83/EntryId/68/Select-First-Log-entery-row-from-Log-Table.aspx אם היית מציגה את השאלה בצורה יותר מסודרת ומצרפת לנו נתונים כגון DDL+DML היה יותר קל יותר לעזור למצוא את הפתרון המתאים ספציפית לבעיה שלך * אין שום סיבה שלא לעשות שימוש ב LINQ שנותן פתרון נהדר במקרה זה כפי שהצגת אבל דווקא במקרה הנוכחי ייתכן ש LINQ לא ייצר לך את השאילתה המיטבית וכתיבה ישירה יכולה להיות יותר יעילה
 

Gooloosh

New member
אני לא משתמשת בLINQ כי הפרוייקט הוא ASP קלאסי

ולא ידוע לי שניתן לעבוד עם LINQ בASP קלאסי (את LINQ אני מכירה מפרוייקטים אחרים...) אם להיות ספציפית יותר אז ככה: יש טבלה עם 2 מליון רשומות מאונדקסות עבור 80 ID. כשאני מגיעה לדף myPage.asp?id=32500&page=15 אז אני עושה
stsql="select * from MYTable where ID=32500" rs.open stsql rs.move 15*10 for i=1 to 10 response.write rs.Fields("value") rs.moveNext next​
הבעיה היא שהשאילתא החזירה לי 3000 רשומות מתוכם הייתי צריכה רק את הרשומות 150-160 וזה בעצם היה מיותר להחזיר את כל ה3000. עד פה היה המצב עד היום בעקבות הבלוג ששלחת לי למדתי על הrowNumber וניסיתי ליישם כך:
with myPagerRows as { select ROW_NUMBER() OVER(ORDER BY relevant DESC) as Row_num, * from MYTable where ID=32500 } select * from myPagerRows WHERE Row_num BETWEEN 10 AND 20;​
האם לכזה פונקציה התכוונת? בכל אופן זה לא עבד נכון אצלי, כי כשאני מריצה את הSELECT הפנימי לבד, ואני בודקת מה הרשומות בין 10-20 אני רואה תוצאות אחרות ממה שהוא מחזיר לי פה.. אתה יכול להסביר לי איפה טעיתי? בתודה
 

pitoach

New member
אני לא מתכוון לקרוא בכלל קוד בלי שיש לי את

היכולת להריץ אותו
אחרי הכל אין לי את הטבלאות שיש לך ואני לא יכול להריץ את השאילתה בכלל אז למה להשקיע לקרוא אותה?!? לא קראתי את השאלה המקורית לעומק ובטח ובטח לא את כל התגובה האחרונה שלך.. זה לא מתוך רוע לב
שימי לב מה רשמתי לך: ציטוט: אם היית מציגה את השאלה בצורה יותר מסודרת ומצרפת לנו נתונים כגון DDL+DML היה יותר קל יותר לעזור למצוא את הפתרון המתאים ספציפית לבעיה שלך והנקודה החשובה היא שכדי שנוכל להריץ אצלנו את מה שאת שואלת עליו ולבדוק מה קורה עלינו לקבל DDL+DML שזה אומר: http://ariely.info/dnn/Blog/newForumsFAQ/ForumsFAQ349/tabid/157 * אני מבין עכשיו יותר נתונים על הבעיה והקישור שהבאתי לא ממש נועד לזה אפילו שכולל חלק מהרעיון אלא נועד להראות עבודה עם פונקציות LAG\LEAD אבל זה לא מה שאת צריכה (לפי מה שאני מבין כרגע) מה שאת מחפשת היא פעולה פשוטה ביותר של חלוקה לעמודים הדרך הכי פשוטה לחלוקה לעמודים היא אכן באמצעות ROW_NUMBER ואז השיטה להוסיף עמודה של ROWNUMBER שממספרת את הרשומות שבוחרים לפי הסדר שרוצים ומתוך התוצאה הזו בוחרים את הנתונים שה ROW_NUMBER שלהם הוא בין: מספר העמוד * מספר הרשומות בעמוד (זה הרשומה הראשונה שבוחרים) עד ל (לא כולל) (מספר העמוד + 1 ) * מספר הרשומות בעמוד ** הערה: ROW_NUMBER לא תמיד נותן את הדרך המיטבית למרות שהוא בדרך כלל דיי יעיל ובעיקר נוח לעבודה. לאחר שיהיה לנו DDL+DML נוכל אולי לדון בנושא של מה טוב יותר גם. תבדקי שיש לך אינדקסים מתאימים בכל מקרה לשאילתות שאת מריצה. *** הערה: גם ב ASP קלאסי אפשר לעבוד עם LINQ אם מפתחים ORM מתאים (EF הוא ORM של דוטנט למשל) אבל זה מורכב וחסר טעם לדעתי כשאפשר תמיד לרשום שאילתות ישירות
 

Gooloosh

New member
הגעתי לפתרון - הסבר

ראיתי שאתה מבקש DDL+DML, אבל זה לא כ"כ אפשרי מבחינתי, הבוס שלי ממש קנאי למבנה הטבלאות, שמות קשרים וכו. והוא לא מוכן ששום איזכור מתוכם יופץ ברשת, ולכן בכל פעם שאני שואלת אני חייבת ליצור איזה שאילתא שתדגים את הבעיה אף פעם היא לא תהיה הבעיה בעצמה.. הפעם חשבתי שזה ממש פשוט, אני בטוחה שאלפי או יותר מתכנתים כבר עשו פייגרים במהלך עבודתם, והיה לי ברור שיש שאילתא יעילה יותר ממה שהצגתי בתחילה לעשות. ולכן נתתי דוגמא עם מבנה של טבלה פשוטה. איך שלא יהיה - המאמר ששלחת אותי אליו, אכן לא היה קשור לבעיה עצמה, אבל מתוכו הגעתי (ע"י חיפוש של מילות המפתח) לפונקציה rowNumber שנראה שיכולה לעזור לי. בסופו של דבר הצלחת לעזור לי :) בשעה שבניתי את הDDL ואת הDML לטבלת הדוגמא, ראיתי שהקוד שכתבתי מקודם אכן עושה את העבודה אז בדקתי שוב מה יכולה להיות הסיבה שזה לא עבד לי על הנתונים האמיתיים, ומצאתי שהשדה לפיו עשיתי את המיון לא היה מספיק יחודי ולכן היו הרבה תוצאות מתאימות וכל פעם הוא נתן 10 אחרים אז הוספתי עוד שדה יחודי למיון אחריו, וזה עבד החיסכון בזמן (לשאילתא של 3000 רשומות במקום 7 שניות - פחות משניה.) אז בכל אופן תודה על הכיוון.. אני מצרפת את הDDL +DML שיצרתי, אולי למישהוא אחר שיחפש את הפתרון לבעיה זו זה יוכל לעזור: (בקובץ המצורף.. מה לעשות תפוז לא הסכים שהוסיף את הקוד כמו שהוא...)
 

pitoach

New member
יפה מאוד. אני מאוד מעריך את הדרך שפעלת

א. הגעת לפתרון סופי לבד (בעזרה שקיבלת אולי לא קיבלת פתרון מוכן סופי ולכן זה אומר שהיה כאן תהליך למידה וזה העיקר לדעתי) ב. חקרת את הנושא שנתקלת בו (אני מציע שאם הגעת כבר לפונקציית ROW_NUMBER אז כדאי שתחקרי פונקציה נוספת באותו סגנון * אני ארשום למטה נקודה קטנה לגבי נושא זה) ג. והעיקר ומעל הכל הבאת לפורום הסבר מלא של הפתרון שבחרת ותיאור של קצר של התהליך ולכן זה יכול יהיה לעזור לאחרים ** נקודה לגבי ROW_NUMBER זו היא פונקציה מסוג פונקציות חלון (החלק שמגיע אחרי ה OVER הוא הגדרה של כאילו חלון נתונים עליה הפונקציה פועלת). ישנם הרבה פונקציות חלון וכל הזמן מוסיפים עוד (בגרסה הבאה של SQL נוספו עוד פונקציות מסוג זה מאוד יעילות) ROW_NUMBER היא הנפוצה ביותר אני חושב אבל אם כבר עברת על פונקציה זו כדאי לפחות לעבור בקצרה על הפונקציה הבאה בתור ואני ממליץ לקרוא על פונקציית RANK. אם הבנת את ROW_NUMBER אז תביני בקלות את כל העבודה של כל פונקציות החלון הבאות ו RANK מאוד מאוד נפוצה ויעילה להמון מקרים (גם את הבעיה שלך אפשר היה למשל לפתור עם RANK במקום עם ROW_NUMBER)
 

Gooloosh

New member
תודה על המחמאות, תמיד נעים לשמוע


בקשר להסבר איך הגעתי לפתרון, זה סוג של הכרת תודה שלי לפורומים, אני נעזרת מידי פעם בפורום, וזו הדרך שלי לעזור גם לאחרים.. בקשר לRANK - אני אציץ גם עליה, תמיד טוב ללמוד משהו חדש וייעיל.
 
למעלה