SQL - שליפת רשומה אחת מעל

ERAN185

New member
SQL - שליפת רשומה אחת מעל

יש לי טבלה שיש בה 2 עמודות - ID , שם
עשיתי שאילתה והתוצאה שקיבלתי היא רשומות שהID שלהן : 3,8,11,14 וכו'
מה הדרך הפשוטה ביותר לקבל את הרשומות שנמצאות שורה אחת מעל - ז"א רשומות שה ID שלהן - 4,9,12,15 וכו'

ערן
 

AvidaEinav

New member
תנסה ככה

CREATE TABLE #TMP(Id INT,NAME VARCHAR(20))
INSERT INTO #TMP
SELECT 3,'a' UNION ALL
SELECT 4,'b' UNION ALL
SELECT 8,'c' UNION ALL
SELECT 9,'d' UNION ALL
SELECT 11,'e' UNION ALL
SELECT 12,'f' UNION ALL
SELECT 14,'g' UNION ALL
SELECT 15,'h' UNION ALL
SELECT 20,'i' UNION ALL
SELECT 30,'j' UNION ALL
SELECT 40,'k' UNION ALL
SELECT 50,'l'

SELECT Id,Name
FROM #TMP
WHERE Id IN(SELECT Id+1 FROM #TMP WHERE Id IN (3,8,11,14)) --Insert your query here.
 

pitoach

New member
חסר נתון קריטי והתשובות שקיבלת בהתאם

1. מה זה אומר "עשיתי שאילתה"
איזה שאילתה בדיוק?!?

לא ניתן לנתק חלק מהשאילתה מה"סך הכל". המכלול הוא לא תמיד חיבור של נקודות, והשאילתה הפנימית שלך בה מצאת את הרשומות המקוריות היא חלק מהשאילתה הסופית.

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

השאילתה שהציעו לך:
SELECT Id,Name
FROM #TMP
WHERE Id IN(SELECT Id+1 FROM #TMP WHERE Id IN (3,8,11,14))

זהה לחלוטין לשאילתה הבאה למשל:
SELECT Id,Name
FROM #TMP
WHERE Id-1 IN (3,8,11,14)

ההבדל במשאבים בין 2 השאילתות ענק! אם מה שרוצים זה את ה ID הקטן יותר אז אפשר כבר בשאילתה המקורית לבקש את ה ID-1 המתאים כפי שאתה רואה בשאילתה ש נייה.

2. האפיון שלך מאוד בעייתי או לא מלא. מה אתה רוצה לקבל במקרה שרשומה נמחקה? למשל נמחוק את רשומה עם ה id = 12 מהטבלה. מה התוצאה שאתה רוצה לקבל כרגע?

לדוגמה: אתה רוצה לקבל את ה ID "שורה אחת מעל" (זו הגדרה בעייתית) ז"א לפני המחיקה דובר על ID = 12 אבל עתה כמחקנו את רשומה זו האם אתה רוצה לקבל את ID = 13 שהוא זה שעתה "שורה אחת מעל" או שאתה רוצה שלא יחזור כלום כי אין ID שהוא בדיוק אחד מעל

* השאילתות שנתנו לך כאן לא יחזירו "שורה אחת מעל" כמו שביקשת, אלא רק את ה ID עם מספר אחד גדול יותר אם הוא קיים. אם ID זה לא קיים הן לא יחזירו את הרשומה "מעל". אחת השיטות אם אתה רוצה תמיד לקבל "שורה אחת מעל" אתה יכול לעבוד עם פונקציית row_number למשל. בגרסת 2012 אתה פשוט עובד עם פונקציית leg או lead. בשרתים ישנים יותר כמו 2000 אתה יכול לעבוד עם שאילתה פנימית. בשרתים מ 2005 אתה יכול לעבוד עם CTE ויש עוד הרבה אפשרויות בהתאם לגרסת השרת איתו אתה עובד.

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

* תוסיף בכל שאילתה שלך את הסידור המתאים אם אתה צריך סדר מסויים.
 

AvidaEinav

New member
אם כבר נגעת בביצועים

*הנחה: על טור ID יש אינדקס כלשהו.

אם נתיחס לסגנון של שאילתא פנימית שדנו עליו פה, ישנם 3 אפשרויות שאפשר לרשום את השאילתא (בקובץ המצורף).

חשוב לשים לב שאת הפעולה החישובית (Id+1/-1) יש לשים בחלק של ה
SELECT ולא ב WHERE כי זה פוגע באפשרות עבודה עם ה INDEX.

ניתן לראות בקובץ גם את ההשלכות על ה Execution plan.

מקווה שזה עזר למשהו במשהו..
 
לא אתה

אלא השואל. חשבתי על מה שאתה אומר, לא היה לי כוח להראות לו את כול מה שחשבתי שזה כול מה שאתה כתבת. וככה ענינו לו.
 
למעלה